BZOJ1029: [JSOI2007]建築搶修

Description
小剛在玩JSOI提供的一個稱之爲“建築搶修”的電腦遊戲:經過了一場激烈的戰鬥,T部落消滅了所有z部落的入侵者。但是T部落的基地裏已經有N個建築設施受到了嚴重的損傷,如果不盡快修復的話,這些建築設施將會完全毀壞。現在的情況是:T部落基地裏只有一個修理工人,雖然他能瞬間到達任何一個建築,但是修復每個建築都需要一定的時間。同時,修理工人修理完一個建築才能修理下一個建築,不能同時修理多個建築。如果某個建築在一段時間之內沒有完全修理完畢,這個建築就報廢了。你的任務是幫小剛合理的制訂一個修理順序,以搶修儘可能多的建築。
Input
第一行是一個整數N,接下來N行每行兩個整數T1,T2描述一個建築:修理這個建築需要T1秒,如果在T2秒之內還沒有修理完成,這個建築就報廢了。
Output
輸出一個整數S,表示最多可以搶修S個建築.N < 150,000; T1 < T2 < maxlongint
Sample Input
4
100 200
200 1300
1000 1250
2000 3200
Sample Output
3
HINT
Source

排序+貪心+小根堆。由“搶修儘量多的建築”可以知道各建築都是等價的,那麼貪心策略爲:1、能搶修的都搶修了。2、若時限內搶修不了,就檢查之前已修好的建築中有沒有不如當前優的(時間比當前長的),替換之。

#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
struct node{
    int t1,t2;
}a[151000];
int n,timenow,ans;
priority_queue<int,vector<int>,less<int> >now;
inline void read(int &x)
{
    x=0;int f=1;char t=getchar();
    while((t<48)or(t>57)){if(t=='-')f=-1;t=getchar();}
    while((t>=48)and(t<=57)){x=(x*10)+t-48;t=getchar();}
    x*=f;
}
bool cmp(node x,node y)
{
    return x.t2<y.t2;
}
int main()
{
    read(n);
    for (int i=1;i<=n;++i) read(a[i].t1),read(a[i].t2);
    sort(a+1,a+n+1,cmp);
    for (int i=1;i<=n;++i)
    if (a[i].t1+timenow<=a[i].t2)
    {
        timenow+=a[i].t1;
        now.push(a[i].t1);
        ++ans;
    }
    else
    {
        if (!now.empty())
        {
            int t=now.top();
            if (a[i].t1<t)
            {
                now.pop();
                timenow-=(t-a[i].t1);
                now.push(a[i].t1);
            }
        }
    }
    printf("%d",ans);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章