51Nod 最高獎勵問題
阿新 • • 發佈:2018-08-10
names 表示 con bre prior def out show bubuko
Question
有N個任務,每個任務有一個最晚結束時間以及一個對應的獎勵。
在結束時間之前完成該任務,就可以獲得對應的獎勵。
完成每一個任務所需的時間都是1個單位時間。
有時候完成所有任務是不可能的,因為時間上可能會有沖突,這需要你來取舍。求能夠獲得的最高獎勵。
Input
第1行:一個數N,表示任務的數量(2 <= N <= 50000)
第2 - N + 1行,每行2個數,中間用空格分隔,表示任務的最晚結束時間E[i]以及對應的獎勵W[i]。
(1 <= E[i] <= 10^9,1 <= W[i] <= 10^9)
Output輸出能夠獲得的最高獎勵。
Input示例
7
4 20
2 60
4 70
3 40
1 30
4 50
6 10
Output示例
230
我想到的第一個思路是:
很麻煩的。。
emm,,
趕時間的話,可忽略。
(按照他能獲得的獎勵從大到小排序)
(如果相等,就讓結束時間靠後的在前面)
(然後用一個數組記錄1到1,1到2,1到3,……1到結束時間最大的那個的空間,也就是在這個空間內,和這個數相等或者小於他的有多少)
(用一個bool數組記錄在某個時間結束這個時間點是否出現過)
(然後循環枚舉,沒有出現就設為出現,ans+=獎勵)
(操作時同時,這個時間點到最大的時間點之間所有的記錄數組都要減一,)(因為在此空間裏又多加了一個數,所以少一個空間)
(然後若是遇到了結束時間相等的,)
(那就判斷一下他前面那個結束時間的位置有沒有被占)
(他前面那個結束時間不是排完序的那個,,是按照1,2,3,4,5……來的那個)
(如果也被占了的話,就繼續往前推)
(在此過程中如果這個結束時間對應的記錄空間的數組等於0的話,(那其實一開始就是0了),)
(那就break掉,不用再繼續了)。
嗯,,基本就是這樣,,
開了很多數組,思路也很麻煩,
可能寫錯了。。
剛開始mle,,最後wa了一個點,t了三四個點。。
代碼是這樣的。:
#include<iostream> #include75.。<cstdio> #include<cmath> #include<algorithm> #include<cstring> #define MAXN 9999 using namespace std; int n,maxn=-1; int b[MAXN],x,s; long long ans; bool c[MAXN],q; struct node{ int end; int value; }a[50002]; bool cmp(node x,node y) { if(x.value !=y.value ) return x.value >y.value ; else return x.end >y.end ; } int main() { scanf("%d",&n); for(int i=1;i<=n;++i) { scanf("%d%d",&a[i].end ,&a[i].value ); maxn=max(maxn,a[i].end ); } for(int i=1;i<=maxn;++i) b[i]=i; sort(a+1,a+n+1,cmp); for(int i=1;i<=n;++i) { x=a[i].end ; s=a[i].value ; if(b[x]) { if(!c[x]) { ans+=s; c[x]=1; for(int j=x;j<=maxn;++j) b[j]--; continue; } while(c[x]) { x--; if(x==0) break; if(!c[x]&&b[x]) { c[x]=1; ans+=s; for(int j=x;j<=maxn;++j) b[j]--; break; } } } } printf("%lld",ans); return 0; }
還是要考慮別的簡單的思路。。
小根堆啊!!!
按照結束時間從小到大排序!
按次序加,
如果有更優的,就把最小的踢出去!!
具體看代碼吧!
手模一遍樣例就懂了!
好強的貪心思路。。。
代碼:
1 #include<queue> 2 #include<cstdio> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 8 priority_queue<int ,vector<int >,greater<int> >q; 9 long long n,ans,s; 10 11 struct node 12 { 13 int end,value; 14 } a[50002]; 15 16 bool cmp(node a,node b) 17 { 18 return a.end<b.end; 19 } 20 21 int main() 22 { 23 scanf("%d",&n); 24 for(int i=1; i<=n; i++) 25 scanf("%d%d",&a[i].end,&a[i].value); 26 sort(a+1,a+1+n,cmp); 27 for(int i=1; i<=n; i++) 28 { 29 s=a[i].value; 30 if(a[i].end>q.size()) 31 { 32 ans+=s; 33 q.push(s); 34 } 35 else 36 { 37 ans+=s; 38 q.push(s); 39 ans-=q.top(); 40 q.pop(); 41 } 42 } 43 printf("%lld",ans); 44 return 0; 45 }
如果你不開心,那我就把右邊這個帥傻子分享給你吧,
你看,他這麽好看,那麽深情的望著你,你還傷心嗎?
真的!這照片盯上他五秒鐘就想笑了。
一切都會過去的。
51Nod 最高獎勵問題