1. 程式人生 > >[BZOJ1029][JSOI2007]建築搶修 貪心+堆

[BZOJ1029][JSOI2007]建築搶修 貪心+堆

names color space mes pro ++ class www get

題目鏈接:http://www.lydsy.com/JudgeOnline/problem.php?id=1029

這道題好像是一道比較經典的貪心,最主要的思路是用堆來提供反悔,修正決策的途徑。

我們首先按每個建築的最晚修復時間排序。然後掃過去,能修就修,並且將修過建築所用的時間加入到堆裏面。

如果遇到了不能修的情況,我們看一下堆頂元素花費的時間與當前所需要的時間的大小關系,如果堆頂元素更大,那麽我們反悔,不修之前那個建築,把時間省下來修當前的建築,然後把所需時間加入堆中。這樣就完成了一次決策的修正。

 1 #include<cstdio>
 2 #include<cstring>
 3
#include<algorithm> 4 #include<queue> 5 using namespace std; 6 typedef long long ll; 7 int inline readint(){ 8 int Num;char ch; 9 while((ch=getchar())<0||ch>9);Num=ch-0; 10 while((ch=getchar())>=0&&ch<=9) Num=Num*10+ch-0; 11 return
Num; 12 } 13 int N; 14 struct Building{ 15 int t1,t2; 16 bool operator < (const Building &_)const{ 17 return t2<_.t2; 18 } 19 }A[150010]; 20 priority_queue <int> q; 21 int main(){ 22 N=readint(); 23 for(int i=1;i<=N;i++){ 24 A[i].t1=readint();
25 A[i].t2=readint(); 26 } 27 sort(A+1,A+1+N); 28 ll ti=0; 29 int ans=0; 30 for(int i=1;i<=N;i++){ 31 if(ti+A[i].t1<=A[i].t2){ 32 ti+=A[i].t1; 33 q.push(A[i].t1); 34 ans++; 35 } 36 else{ 37 int tmp=q.top(); 38 if(tmp>A[i].t1){ 39 q.pop(); 40 ti-=tmp-A[i].t1; 41 q.push(A[i].t1); 42 } 43 } 44 } 45 printf("%d\n",ans); 46 return 0; 47 }

[BZOJ1029][JSOI2007]建築搶修 貪心+堆