HDU 6781 Solo (貪心 + 優先佇列)
阿新 • • 發佈:2020-07-27
Solo
Time Limit: 2000/1000 MS (Java/Others)Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 115Accepted Submission(s): 51
比賽一共有n個題,編號為1,2....,n,對於第i道題,Alice 需要a[i]分鐘寫出一份正確的程式碼,Bob 需要b[i]分鐘寫出一份正確的程式碼。
比賽規則為
1. 每道題第一個通過的人積 1 分,如果兩人同時 AC 該題,只有 Alice 得分。
2. 比賽時長為1018
Alice 和 Bob 的比賽策略都滿足:決定要去做某道題後,會一直解決該題,直到自己或者對手 AC 此題,如果對手 AC 該題,則會立即放棄這題。
Bob 寫完一份正確的程式碼後會立即提交,但 Alice 寫完一份正確的程式碼,可以先暫時不交題,等之後再交(交題的時間忽略不計,任何時間都可以交題)。
另外 Alice 知道 Bob 是按1,2,....,n的順序來依次做題,知道每道題自己需要的時間和 Bob 需要的時間(即a序列和b序列)。
輸出 Alice 最優策略下最多得幾分。
Alice 和 Bob 想題都不需要時間。 Input 第一行一個整數t(1≤t≤10)表示t組資料。
每組資料第一行一個整數n(1≤n≤2000)表示題數。
第二行n個整數,表示a[1],a[2],...a[n](1≤a[i]≤1000000000)。
第三行n個整數,表示b[1],b[2],...b[n](1≤b[i]≤1000000000)。
保證至多隻有一組資料n>100。 Output 對於每組資料,一行一個整數表示答案。 Sample Input 2 6 6 6 6 6 6 6 1 1 1 1 1 1 3 1 2 3 5 1 1 Sample Output 1 3 樣例解釋 Case 1 開場直接 rush 最後一題。 Case 2 [0,1) 寫掉第一題,第 5 分鐘交;[1,3) 寫第二題第 6 分鐘交,[3,6) 寫第三題第 6 分鐘交。
析:這個題和官方題解也不一致,沒有使用動態規劃,由於Alice可以做出題不提交,那麼最優的策略一定是和Bob一起提交,所以Bob的每個題的提交時間都是固定的,然後只需要計算出Alice每個題的最晚結束時間,然後放到一個優先佇列中,時間最長的在最頂層,然後對於每個題,先考慮能不能正常完成,如果能夠按照做完,則直接放到佇列中,如果不能,則需要比較佇列中時間最長的題目比較,如果刪除那個最長的題目,能夠把當前的題目做出來,就把以前的題目刪掉,把當前的題目放進去,為什麼呢,因為當前題目比較短,可以為後面的題目提供更多的時間,這個策略就是最優的,最後佇列中的所有題目都是能得到積分的。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <iostream> #include <cstring> #include <set> #include <queue> #include <algorithm> #include <vector> #include <map> #include <cctype> #include <cmath> #include <stack> #include <sstream> #include <list> #include <assert.h> #include <bitset> #include <numeric> #include <unordered_map> #define debug() puts("++++") #define print(x) cout<<(x)<<endl // #define gcd(a, b) __gcd(a, b) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define fi first #define se second #define pb push_back #define sqr(x) ((x)*(x)) #define ms(a,b) memset(a, b, sizeof a) #define sz size() #define be begin() #define ed end() #define pu push_up #define pd push_down #define cl clear() #define lowbit(x) -x&x #define all 1,n,1 #define FOR(i,n,x) for(int i = (x); i < (n); ++i) #define freopenr freopen("in.in", "r", stdin) #define freopenw freopen("out.out", "w", stdout) using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int, int> P; const int INF = 0x3f3f3f3f; const LL LNF = 1e17; const double inf = 1e20; const double PI = acos(-1.0); const double eps = 1e-8; const int maxn = 2e3 + 7; const int maxm = 2000000 + 7; const LL mod = 1e9 + 7; const int dr[] = {-1, 1, 0, 0, 1, 1, -1, -1}; const int dc[] = {0, 0, 1, -1, 1, -1, 1, -1}; int n, m; inline bool is_in(int r, int c) { return r >= 0 && r < n && c >= 0 && c < m; } inline int readInt(){ int x; scanf("%d", &x); return x; } LL a[maxn], b[maxn]; unordered_map<int, int> mp; struct Task{ LL l, r, len; bool operator < (const Task &t) const{ if(len != t.len) return len < t.len; if(r != t.r) return r > t.r; return l > t.l; } }; int main(){ int T; scanf("%d", &T); while(T--){ scanf("%d", &n); for(int i = 1; i <= n; ++i) scanf("%lld", a + i); for(int i = 1; i <= n; ++i) scanf("%lld", b + i), b[i] += b[i-1]; priority_queue<Task> pq; LL time = 0; for(int i = 1; i <= n; ++i){ if(a[i] + time <= b[i]){ pq.push((Task){time, a[i]+time, a[i]}); time += a[i]; } else if(!pq.empty()){ Task t = pq.top(); if(time + a[i] - t.len <= b[i]){ pq.pop(); pq.push((Task){time-t.len, time-t.len+a[i], a[i]}); time += a[i] - t.len; } } } printf("%d\n", pq.sz); } return 0; }