1. 程式人生 > >bzoj1029[JSOI2007]建築搶修

bzoj1029[JSOI2007]建築搶修

HR 需要 lin desc sam cmp pan lib 下一個

傳送門

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

題解

意識到這是一道挺2的題……

我們考慮到:若在建築報廢之前修好,無論何時修,結果都是一樣的。因此我們將所有數據按照報廢時間排序,用優先隊列維護當前被選擇的答案的從大到小排序順序。如果能夠接著在指定時間內完成則將其直接插入優先隊列中,否則將修理的時間與優先隊列中的最大值進行比較,如果比最大值小,則不去修最大值所在建築改為去修該建築則會更優。由於我們按照完成時間排序,所以不需要擔心是否會超出時間。

代碼

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<vector>
 8 #include<queue>
 9 using namespace std;
10 priority_queue<int> pq;
11 struct node{
12     int
re,ot; 13 }a[150010]; 14 int n,now,ans; 15 bool cmp(node a,node b){ 16 return a.ot<b.ot; 17 } 18 int main(){ 19 scanf("%d",&n); 20 int i,j; 21 for(i=1;i<=n;++i){ 22 scanf("%d%d",&a[i].re,&a[i].ot); 23 } 24 sort(a+1,a+1+n,cmp); 25 now=0;ans=0; 26 for(i=1;i<=n;++i){ 27 if(a[i].re+now<=a[i].ot){ 28 ans++;now+=a[i].re; 29 pq.push(a[i].re); 30 } 31 else{ 32 int tot=pq.top(); 33 if(a[i].re<tot){ 34 pq.pop();pq.push(a[i].re); 35 now=now-tot+a[i].re; 36 } 37 } 38 } 39 printf("%d\n",ans); 40 return 0; 41 }

bzoj1029[JSOI2007]建築搶修