1. 程式人生 > >[bzoj1029] [JSOI2007]建築搶修

[bzoj1029] [JSOI2007]建築搶修

() esp out getchar() spa else == solution define

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 

Solution

貪心。

先按自爆時間排序,然後一個一個做。

如果當前能修就修,否則看看前面修的所花的最長的時間是不是大於當前需要的時間,如果是,那麽前面那個就不修了,改為修當前這個。

正確性比較顯然,考慮修這個和修以前那個答案相同,顯然選花的總時間最小的那個最優。

#include<bits/stdc++.h>
using namespace std;

void read(int &x) {
    x=0;int f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}

#define write(x) printf("%d\n",x)

const int maxn = 2e5+10;

int n;

struct data {
    int t,x;
    bool operator < (const data &rhs) const {return x<rhs.x;}
}r[maxn];

priority_queue <int > s;

int main() {
    read(n);for(int i=1;i<=n;i++) read(r[i].t),read(r[i].x);
    int now=0,ans=0;
    sort(r+1,r+n+1);
    for(int i=1;i<=n;i++) {
        if(now+r[i].t<=r[i].x) ans++,now+=r[i].t,s.push(r[i].t);
        else if(s.top()>r[i].t) now+=r[i].t-s.top(),s.pop(),s.push(r[i].t); 
    }write(ans); 
    return 0;
}

[bzoj1029] [JSOI2007]建築搶修