[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;
}
posted @ 2018-03-02 08:37  Vanisher  阅读(63)  评论(0编辑  收藏  举报