[JSOI2007] 建筑抢修

题目描述

小刚在玩 JSOI 提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,T 部落消灭了所有 Z 部落的入侵者。但是 T 部落的基地里已经有 \(N\) 个建筑设施受到了严重的损伤,如果不尽快修复的话,这些建筑设施将会完全毁坏。现在的情况是:T 部落基地里只有一个修理工人,虽然他能瞬间到达任何一个建筑,但是修复每个建筑都需要一定的时间。同时,修理工人修理完一个建筑才能修理下一个建筑,不能同时修理多个建筑。如果某个建筑在一段时间之内没有完全修理完毕,这个建筑就报废了。你的任务是帮小刚合理的制订一个修理顺序,以抢修尽可能多的建筑。

输入格式

第一行,一个整数 \(N\)

接下来 \(N\) 行,每行两个整数 \(T_1,T_2\) 描述一个建筑:修理这个建筑需要 \(T_1\) 秒,如果在 \(T_2\) 秒之内还没有修理完成,这个建筑就报废了。

输出格式

输出一个整数 \(S\),表示最多可以抢修 \(S\) 个建筑。

样例 #1

样例输入 #1

4
100 200
200 1300
1000 1250
2000 3200

样例输出 #1

3

提示

对于 \(100 \%\) 的数据,\(1 \le N < 150000\)\(1 \le T_1 < T_2 < 2^{31}\)

解析

将截止时间按升序排序,记录一个变量now表示当前一共花的时间,枚举每个建筑,如果now加上当前建筑所需时间不超过他的截止时间,那么答案加一,将他的时间花费加入大根堆;大于截止时间的话,判断一下当前建筑的花费是否小于堆顶,小于则删去堆顶将其入堆(因为该建筑的花费小,且截止时间又不小于堆顶,选择修建他肯定更优),基于贪心思路,使得now尽量小,这样后面的建筑更有机会被修建。

代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 150010;
struct node {
	int x, y;
}a[N];
bool cmp(node a, node b) {
	return a.y < b.y;
}
priority_queue<int> q;
signed main() {
	int n;
	cin >> n;
	for (int i = 1; i <= n; i ++) cin >> a[i].x >> a[i].y;
	sort(a + 1, a + n + 1, cmp);
	int now = 0, ans = 0;
	for (int i = 1; i <= n; i ++) {
		if (now + a[i].x <= a[i].y) {
			ans ++;
			now += a[i].x;
			q.push(a[i].x);
		}
		else if (a[i].x < q.top()) {
			now = now - q.top() + a[i].x;
			q.pop(), q.push(a[i].x);
		}
	}
	cout << ans << '\n';
}

image

原文地址:http://www.cnblogs.com/YHxo/p/16791506.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性