BZOJ 1029: [JSOI2007]建筑抢修
http://www.lydsy.com/JudgeOnline/problem.php?id=1029
/*
* 题目:
* 每个任务需要ai时间完成,并且需要在时间bi或之前完成,问如何安排任务完成顺序,使得完成
* 任务的数量最多
*
* 分析:
* 贪心,先对期限排序,然后用最大堆维护需要完成的时间ai
* 1.当now + ai <= bi时,ans + 1 ,更新now,把ai插入到堆中
* 2.当now + ai > bi时,若堆的最大元素大于ai时,将该元素(aj,bj)替换为ai,得到的序列答案
* 不会减少。因为替换之后,时间期限bi必定大于bj,所以可以完成该任务,另外替换之后,所需的
* 时间减少了,所以替换是正确的。
*
* */
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int X = 150005; #define debug puts("here"); struct Heap{ int a[X]; int s; void insert(int x){ a[++s] = x; for(int i=s;i>1;i>>=1){ if(a[i] > a[i>>1]) swap(a[i],a[i>>1]); else break; } } void down(int x){ a[1] = x; int i = 1; int j = 2; while(j<=s){ if(j+1<=s && a[j+1]>a[j]) j ++; if(a[j]>a[i]){ swap(a[i],a[j]); i = j; j <<= 1; } else break; } } void init(){ memset(a,0,sizeof(a)); s = 0; } void display(){ for(int i=1;i<=s;i++) cout<<a[i]<<" "; cout<<endl; } }heap; struct node{ int last,time; friend bool operator < (node a,node b){ return a.time < b.time || (a.time==b.time&&a.last<b.last); } }p[X]; int main(){ int n; while(cin>>n){ for(int i=0;i<n;i++) scanf("%d%d",&p[i].last,&p[i].time); sort(p,p+n); heap.init(); int now = 0; int ans = 0; for(int i=0;i<n;i++){ if(now+p[i].last<=p[i].time){ ans ++; now += p[i].last; heap.insert(p[i].last); } else if(heap.a[1]>p[i].last){ now -= heap.a[1]-p[i].last; heap.down(p[i].last); } //heap.display(); } cout<<ans<<endl; } return 0; }