BZOJ1029 [JSOI2007] 建筑抢修
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1029
Description
小刚在玩JSOI提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者。但是T部落的基地里已经有N个建筑设施受到了严重的损伤,如果不尽快修复的话,这些建筑设施将会完全毁坏。现在的情况是:T部落基地里只有一个修理工人,虽然他能瞬间到达任何一个建筑,但是修复每个建筑都需要一定的时间。同时,修理工人修理完一个建筑才能修理下一个建筑,不能同时修理多个建筑。如果某个建筑在一段时间之内没有完全修理完毕,这个建筑就报废了。你的任务是帮小刚合理的制订一个修理顺序,以抢修尽可能多的建筑。
Input
第一行是一个整数N,接下来N行每行两个整数T1,T2描述一个建筑:修理这个建筑需要T1秒,如果在T2秒之内还没有修理完成,这个建筑就报废了。
Output
输出一个整数S,表示最多可以抢修S个建筑.N < 150,000; T1 < T2 < maxlongint
简单的贪心
用堆维护之前占用时间最多的任务
对所有任务按照deadline从前到后排序,枚举每一个任务:
1. 如果最近的空闲时间点加上当前任务的时间小于deadline就入堆,更新答案
2. 如果最近的空闲时间点加上当前任务的时间大于deadline,且该任务完成用时小于前面的最大用时,将该任务入堆,前面最大的扔掉,更新最后的空闲时间点
第一次交的时候打错了……
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <queue> 6 #define rep(i,l,r) for(int i=l; i<=r; i++) 7 using namespace std; 8 const int maxn = 150010; 9 struct building{ 10 int c,t; 11 inline bool operator < (const building &_Tp) const{ 12 return t < _Tp.t; 13 } 14 }b[maxn]; 15 int n,now=0,ans=0; 16 priority_queue <int,vector<int>,less<int> > q; 17 inline int read(){ 18 int ans = 0, f = 1; 19 char c = getchar(); 20 while (!isdigit(c)){ 21 if (c == '-') f = -1; 22 c = getchar(); 23 } 24 while (isdigit(c)){ 25 ans = ans * 10 + c - '0'; 26 c = getchar(); 27 } 28 return ans * f; 29 } 30 int main(){ 31 n = read(); 32 rep(i,1,n) b[i].c = read(), b[i].t = read(); 33 sort(b+1,b+n+1); 34 rep(i,1,n){ 35 if (now + b[i].c <= b[i].t){ 36 ans++; 37 now += b[i].c; 38 q.push(b[i].c); 39 } 40 else{ 41 int temp = q.top(); 42 if (b[i].c < temp){ 43 q.pop(); 44 q.push(b[i].c); 45 now = now - temp + b[i].c; 46 } 47 } 48 } 49 printf("%d\n",ans); 50 return 0; 51 }