bzoj 1029: [JSOI2007]建筑抢修 贪心

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 1029: [JSOI2007]建筑抢修 贪心相关的知识,希望对你有一定的参考价值。

题目链接

1029: [JSOI2007]建筑抢修

Time Limit: 4 Sec  Memory Limit: 162 MB
Submit: 3280  Solved: 1473
[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
 
按右边的坐标先排个序, 然后对于每一个, 看当前时间+所需时间是否大于期限, 如果小于, ans++, 然后把这个所需的时间加到一个优先队列里面。 如果大于, 那么看队列顶的元素是否大于当前元素的时间, 如果大于, 就把队列顶的元素出队列, 当前元素加入队列, 并且now也做相应的更改。  具体可以看代码, 很清楚。
#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <bitset>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int mod = 1e9+7;
const int inf = 1061109567;
const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
struct node
{
    int l, r, t;
    bool operator < (node a) const
    {
        if(r == a.r)
            return l<a.l;
        return r<a.r;
    }
}a[150005];
priority_queue <int, vector<int>, less<int> > q;
int main()
{
    int n, x;
    cin>>n;
    for(int i = 0; i<n; i++) {
        scanf("%d%d", &a[i].t, &a[i].r);
        a[i].l = a[i].r-a[i].t;
    }
    sort(a, a+n);
    int ans = 0, now = 0;
    for(int i = 0; i<n; i++) {
        if(a[i].l>=now) {
            ans++;
            now += a[i].t;
            q.push(a[i].t);
        } else {
            int tmp = q.top();
            if(tmp>a[i].t) {
                now = now-tmp+a[i].t;
                q.pop();
                q.push(a[i].t);
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

 

以上是关于bzoj 1029: [JSOI2007]建筑抢修 贪心的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ-1029: [JSOI2007]建筑抢修(贪心+堆优化)

BZOJ1029: [JSOI2007]建筑抢修(贪心)

BZOJ1029: [JSOI2007]建筑抢修[模拟 贪心 优先队列]

BZOJ 1029: [JSOI2007]建筑抢修 堆+贪心

bzoj 1029 [JSOI2007]建筑抢修 - 贪心 + 大根堆

BZOJ 1029: [JSOI2007]建筑抢修优先队列+贪心策略