[洛谷P2107] 小Z的AK計劃
阿新 • • 發佈:2018-10-05
pre top names 然而 yqi 解題思路 情況 show getc 就死往\(DP\)裏鉆……其實可能根本不是\(DP\)而是貪心。貪心和\(DP\)在很多情況下同時適用於一個問題。
題目類型:貪心,堆
傳送門:>Here<
題意:給出\(N\)個房間,每個房間距離起點的距離為\(x[i]\),每個房間可以選擇進去和不進去,如果進去了那麽要\(t[i]\)秒後才能出來。問在\(M\)秒內最多能進多少個房間
解題思路
第一眼是一個\(01\)背包,然而枚舉當前房間和上一個房間,加上所用時間,復雜度\(O(n^3)\)……
考慮枚舉終點,這樣所有路上的時間之和就可以確定了。然後就是看在剩余的時間裏最多能去幾個房間,這個很簡單——假設全去,如果超時,那麽每次踢出耗時最多的那個房間。每次踢出最大的,用一個大根堆維護即可。復雜度\(O(nlogn)\)
反思
不要認為一道題是\(DP\)
不能被題目迷惑……題目所說的距離和進入房間所需要的都是時間,好像混為一談。實際上要是割裂開來看就異常簡單了。
Code
/*By DennyQi 2018*/ #include <cstdio> #include <queue> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; #define int ll const int MAXN = 100010; const int INF = 1061109567; inline int Max(const int a, const int b){ return (a > b) ? a : b; } inline int Min(const int a, const int b){ return (a < b) ? a : b; } inline int read(){ int x = 0; int w = 1; register char c = getchar(); for(; c ^ '-' && (c < '0' || c > '9'); c = getchar()); if(c == '-') w = -1, c = getchar(); for(; c >= '0' && c <= '9'; c = getchar()) x = (x<<3) + (x<<1) + c - '0'; return x * w; } struct Room{ int x, t; }a[MAXN]; inline bool operator < (const Room& a, const Room& b){ return a.t < b.t; } int N,M,ans,sum,cnt; priority_queue <Room> q; inline bool pos_cmp(const Room& a, const Room& b){ return a.x < b.x; } signed main(){ N = read(), M = read(); for(int i = 1; i <= N; ++i){ a[i].x = read(); a[i].t = read(); } sort(a+1, a+N+1, pos_cmp); for(int i = 1; i <= N; ++i){ q.push((Room){a[i].x, a[i].t}); sum += a[i].t + a[i].x - a[i-1].x; while(sum > M && q.size()){ sum -= q.top().t; q.pop(); --cnt; } ++cnt; ans = Max(ans, cnt); } printf("%d", ans); return 0; }
[洛谷P2107] 小Z的AK計劃