打地鼠游戏(贪心)
照例化简题意:
0点n个任务,每个任务有一个权值和一个消失时间,要在消失之前完成才会获得价值,求最大值
solution:
蒟蒻一开始居然往dp上想。。。
集训的东西,我却忘了,看来还没消化完啊。。。
最后歪歪出来一个类似正解的东西但是我搞崩掉了....
首先,在每个点完成消失的东西,然后在空闲的点找最大的完成。
貌似是对的.....(至少hack date都过了)
然后正解:
用课件的话来讲,就是:
- 时光倒流
- 用堆维护
这就很好理解了。。
先排序
然后往大根堆里面塞一个最大值(如果不超过消失时间的话)
如果超过了当前时间,找之前的一个不超过时间的最大值塞进大根堆里
然后最后统计答案。
#include<bits/stdc++.h> using namespace std; const int maxn=1e6+10; inline int read() { int x=0,f=1;char s=getchar(); while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();} while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();} return x*f; } struct node { int t,p; }a[maxn]; bool operator<(node a,node b) { return a.t<b.t; } int n,now=0,ans; priority_queue < int , vector < int > , greater < int > > q; int main() { n=read(); for(int i=1;i<=n;i++) { a[i].t=read(); } for(int i=1;i<=n;i++) { a[i].p=read(); } sort(a+1,a+n+1); for(int i=1;i<=n;i++) { if(now<a[i].t) { now++; q.push(a[i].p); ans+=a[i].p; } else { int t=q.top(); if(t>a[i].p) continue; else { ans=ans-t+a[i].p; q.pop(); q.push(a[i].p); } } } printf("%d",ans); return 0; }
(完)