[bzoj1029][JSOI2007]建筑抢修【贪心】【堆】
【题目链接】
http://www.lydsy.com/JudgeOnline/problem.php?id=1029
【题解】
按时间T2从早到晚排序,依次取,把当前的决策集合按T1为关键字放入大根堆里去,新来一个建筑时,若能取则直接取,否则与堆顶元素比较,若小于堆顶的T1则将堆顶弹出并选择它。
/* --------------
user Vanisher
problem bzoj-1029
----------------*/
# include <bits/stdc++.h>
# define ll long long
# define N 200010
using namespace std;
int read(){
int tmp=0, fh=1; char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();}
while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar();}
return tmp*fh;
}
struct node{
int a,b;
}t[N];
bool cmp(node a, node b){
return a.b<b.b;
}
priority_queue <int> hp;
int n,now,num;
int main(){
n=read();
for (int i=1; i<=n; i++)
t[i].a=read(), t[i].b=read();
sort(t+1,t+n+1,cmp);
now=0; num=0;
for (int i=1; i<=n; i++){
now=now+t[i].b-t[i-1].b;
if (now>=t[i].a){
hp.push(t[i].a);
now-=t[i].a;
num++;
}
else {
if (t[i].a<hp.top()){
now=now+hp.top()-t[i].a;
hp.pop(); hp.push(t[i].a);
}
}
}
printf("%d\n",num);
return 0;
}