[BZOJ1029][JSOI2007]建筑抢修

1029: [JSOI2007]建筑抢修

Time Limit: 4 Sec  Memory Limit: 162 MB Submit: 5107  Solved: 2267 [Submit][Status][Discuss]

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
 
按照结束时间排序,然后每次考虑能否直接把当前加入维修序列,若不能直接加入,则把维修序列中耗时最多且比当前的还多的那个替换掉
用堆维护即可
#include <queue>
#include <cstdio>
#include <algorithm>
using namespace std;
inline int readint(){
    int f = 1, n = 0;
    char ch = getchar();
    while(ch < '0' || ch > '9'){
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(ch <= '9' && ch >= '0'){
        n = (n << 1) + (n << 3) + ch - '0';
        ch = getchar();
    }
    return f * n;
}
const int maxn = 150000 + 10;
struct Node{
    int a, b;
}no[maxn], t;
class cmp1{
public:
    bool operator () (const Node &x, const Node &y){
        return x.b < y.b;
    }
};
class cmp2{
public:
    bool operator () (const Node &x, const Node &y){
        return x.a < y.a;
    }
};
priority_queue<Node, vector<Node>, cmp2> q;
int main(){
    int N = readint();
    for(int i = 1; i <= N; i++){
        no[i].a = readint();
        no[i].b = readint();
    }
    sort(no + 1, no + N + 1, cmp1());
    int tot = 0;
    for(int i = 1; i <= N; i++){
        if(tot + no[i].a <= no[i].b){
            tot += no[i].a;
            q.push(no[i]);
        }
        else if(!q.empty()){
            t = q.top();
            if(no[i].a < t.a){
                q.pop();
                q.push(no[i]);
                tot -= t.a - no[i].a;
            }
        }
    }
    printf("%d\n", q.size());
    return 0;
}

 

posted @ 2017-08-28 20:12  jzyy  阅读(142)  评论(0编辑  收藏  举报