BZOJ 1029 [JSOI2007]建筑抢修 贪心
顺利,思路大概是是这样,按照任务截止的时间从小到大排序,如果任务截止的时间相同就按任务执行的时间从大到小排序(后面再说为什么),并存进一个队列里。然后依次把这些任务从队列中取出按顺序执行,如果某次发现不满足,那么就在之前处理过的任务中取出执行时间最长的减去。(所以我就把任务按执行时间从大到小排序了)。思想大致若此,跑了400多毫秒。
1 #include<cstdio> 2 #include<iostream> 3 #include<queue> 4 #define rep(i,j,k) for(int i = j; i <= k; i++) 5 using namespace std; 6 7 priority_queue<int> p; 8 9 struct node{ 10 int time, zhi; 11 node(int time,int zhi):time(time), zhi(zhi) {}; 12 bool operator < (const node &rhs) const { 13 return zhi > rhs.zhi || (zhi == rhs.zhi && time < rhs.time); 14 } 15 }; 16 priority_queue<node> q; 17 18 int read() 19 { 20 int s = 0, t = 1; char c = getchar(); 21 while( !isdigit(c) ){ 22 if( c == '-' ) t = -1; c = getchar(); 23 } 24 while( isdigit(c) ){ 25 s = s * 10 + c - '0'; c = getchar(); 26 } 27 return s * t; 28 } 29 30 int main() 31 { 32 int n = read(); 33 rep(i,1,n){ 34 int time = read(), zhi = read(); 35 q.push(node(time,zhi)); 36 } 37 int cost = 0, tot = 0; 38 rep(i,1,n){ 39 node u = q.top(); q.pop(); 40 int time = u.time, zhi = u.zhi; 41 p.push(time); 42 cost += time; 43 tot++; 44 if( cost > zhi ){ 45 int k = p.top(); p.pop(); 46 cost -= k, tot--; 47 } 48 } 49 cout<<tot<<endl; 50 return 0; 51 }
1029: [JSOI2007]建筑抢修
Time Limit: 4 Sec Memory Limit: 162 MBSubmit: 3147 Solved: 1416
[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
100 200
200 1300
1000 1250
2000 3200
Sample Output
3
HINT
Source
————————————————