JZYZOJ1622 [usaco2009]工作安排 贪心

和p1123智力大冲浪一样,可以用优先队列写...
 
每一秒可以做一个工作....因为n个任务只要在限制之前完成就行,所以时间不冲突的话肯定越早做完越好..所以最多的时间是n,当然限定的完成时间中最大的可能小于n,或者有的时间重叠什么的,所以大多数情况用不了n个时间....
 
所以我们就可以以时间为变量制造一个贪心,int now代表做一个工作前的时间,ans代表最大值,把工作按照时间顺序排序,然后不停地把p_i加到ans里,加进去一个now++一次,只要now不超过b_i就完全没有问题;
但是b_i<now+1了我们就需要去掉之前加进去的最小的那个工作然后now--(包括i),找最小这种事情就要优先队列来做...
 
那么now--后怎么就能确保now+1<=b_i?
这个东西和开始扫描前的排序有关系了,因为b_(i-1)肯定能放进去,那么当时now+1<=b_(i-1);而b_i>=b_(i-1),那么b_(i-1)放进去后now++一次就说明这个时候now<=b_i,然后就证明了这个问题;
那么b_(i-1)为什么能放进去?只需要往前推就好了啊...第一个任务肯定是能放进去的...
 
嗯没有下面了
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<iostream>
 5 #include<cmath>
 6 #include<queue>
 7 using namespace std;
 8 long long n;
 9 struct wtff{
10     long long d,p;
11 }wtf[100010];
12 priority_queue< long long >q;
13 bool mycmp(wtff a,wtff b){
14     return (a.d<b.d||
15     (a.d==b.d&&a.p<b.p));
16 }
17 int main(){
18     long long ans=0;
19     cin>>n;
20     for(int i=1;i<=n;i++){
21         scanf("%lld%lld",&wtf[i].d,&wtf[i].p);
22     }
23     sort(wtf+1,wtf+1+n,mycmp);
24     int now=0;
25     for(int i=1;i<=n;i++){
26         ans+=wtf[i].p;
27         now++;
28         q.push(-wtf[i].p);
29         if(now>wtf[i].d){
30             ans+=q.top();
31             q.pop();
32             now--;
33         }
34     }
35     cout<<ans<<endl;
36     return 0;
37 }
View Code

 

 
posted @ 2017-11-04 16:28  鲸头鹳  阅读(141)  评论(0编辑  收藏  举报