洛谷 P2949 [USACO09OPEN]Work Scheduling G(反悔贪心)

传送门


解题思路

反悔贪心。排序后,枚举时间,每次能加就加,并且把对应权值扔到小根堆里,若不能加,就把权值和小根堆堆顶比较,若更优,则换成这个任务,把原来那个踢出堆顶,扔进这个点,并且ans加上两个点的权值差。

注意ans要用long long保存,不然会惨遭41分。

AC代码

 1 #include<iostream>
 2 #include<cmath>
 3 #include<cstring>
 4 #include<queue>
 5 #include<algorithm>
 6 #include<cstdio>
 7 using namespace std;
 8 const int maxn=100005;
 9 int n,num=1;
10 long long ans;
11 struct node{
12     int d,p;
13 }a[maxn];
14 bool cmp(node a,node b){
15     return a.d==b.d?a.p>b.p:a.d<b.d;
16 }
17 priority_queue<int,vector<int>,greater<int> > q;
18 int main(){
19     cin>>n;
20     for(int i=1;i<=n;i++){
21         scanf("%d%d",&a[i].d,&a[i].p);
22     }
23     sort(a+1,a+n+1,cmp);
24     for(int i=1;i<=a[n].d;i++){
25         while(num<=n&&a[num].d>=i){
26             q.push(a[num].p);
27             ans+=a[num].p;
28             i++;
29             num++;
30         }
31         i--;
32         if(num>n) break;
33         while(num<=n&&(a[num].d==a[num-1].d)){
34             if(q.top()<a[num].p){
35                 ans+=a[num].p-q.top();
36                 q.pop();
37                 q.push(a[num].p);
38             }
39             num++;
40         }
41     }
42     cout<<ans;
43     return 0;
44 } 

 

posted @ 2020-11-04 20:19  尹昱钦  阅读(183)  评论(0编辑  收藏  举报