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
 
按T2排序,用一个堆维护选择修的建筑。每次加入后判断时间是否够,不够就放弃修用时最长的建筑。
#include<cstdio>
#include<cctype>
#include<queue>
#include<cmath>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
const int BufferSize=1<<16;
char buffer[BufferSize],*head,*tail;
inline char Getchar() {
    if(head==tail) {
        int l=fread(buffer,1,BufferSize,stdin);
        tail=(head=buffer)+l;
    }
    return *head++;
}
inline int read() {
    int x=0,f=1;char c=Getchar();
    for(;!isdigit(c);c=Getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=Getchar()) x=x*10+c-'0';
    return x*f;
}
const int maxn=150010;
struct Building {
    int need,t;
    bool operator < (const Building& ths) const {return t<ths.t;}
}A[maxn];
priority_queue<int> Q;
int main() {
    int n=read(),t=0;
    rep(i,1,n) A[i].need=read(),A[i].t=read();
    sort(A+1,A+n+1);
    rep(i,1,n) {
        Q.push(A[i].need);t+=A[i].need;
        while(t>A[i].t) t-=Q.top(),Q.pop();
    }
    printf("%d\n",Q.size());
    return 0;
}
View Code

 

posted @ 2015-12-05 14:16  wzj_is_a_juruo  阅读(209)  评论(0编辑  收藏  举报