51Nod 最高奖励问题
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> #include<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 }
如果你不开心,那我就把右边这个帅傻子分享给你吧,
你看,他这么好看,那么深情的望着你,你还伤心吗?
真的!这照片盯上他五秒钟就想笑了。
一切都会过去的。