洛谷 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 }