bzoj 1029 [ JSOI 2007 ] 建筑抢修 —— 贪心

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1029

想不出来贪心...

首先把任务按结束时间排序;

因为任务一定是越提前做越好,所以从头开始往后做任务,时间增加,记录 nw;

新加入一个任务,如果能够完成,那么完成即可;

如果不行,从已经完成的任务中找一个替换使时间提前的,这样答案不变但是 nw 更小,为后面提供更大的空间;

注意替换掉的要比当前任务花费的时间长!

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int const maxn=150005;
int n,nw,ans;
priority_queue<int>q;
struct N{int t,d;}p[maxn];
bool cmp(N x,N y){return x.d<y.d;}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d%d",&p[i].t,&p[i].d);
    sort(p+1,p+n+1,cmp);
    for(int i=1;i<=n;i++)
    {
        if(nw+p[i].t<=p[i].d)
        {
            nw+=p[i].t; ans++;
            q.push(p[i].t);
        }
        else if(q.size()&&q.top()>p[i].t&&nw-q.top()+p[i].t<=p[i].d)//q.top()>p[i].t!
        {
            nw-=q.top(); nw+=p[i].t;
            q.pop(); q.push(p[i].t);
        }
    }
    printf("%d",ans);
    return 0;
}

 

posted @ 2018-07-25 16:17  Zinn  阅读(138)  评论(0编辑  收藏  举报