【BZOJ1029】【JSOI2007】【建築搶修】【貪心+堆】
阿新 • • 發佈:2017-06-27
namespace 一段 new -c iostream man mes mod priority
100 200
200 1300
1000 1250
2000 3200
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
4100 200
200 1300
1000 1250
2000 3200
Sample Output
3 題解:貪心策略比較顯然。我們按T2排序,然後從頭開始掃,假設能進行搶修。就進行搶修,否則在之前搶修過的建築中找一個T1最大的。看一下用當前建築取代它會不會更優。假設是就替換。。求最大值的時候用堆優化一下就好了。。
#include<iostream> #include<cstdio> #include<queue> #include<algorithm> using namespace std; int n,now,ans; struct use{ int last,end; }e[1000001]; priority_queue<int>q; bool cmp(use a,use b){return a.end<b.end;} int main() { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d%d",&e[i].last,&e[i].end); sort(e+1,e+n+1,cmp); now=0; for (int i=1;i<=n;i++) if (now+e[i].last<=e[i].end){ans++;q.push(e[i].last);now+=e[i].last;} else { int x; if (!q.empty()) { x=q.top(); if (x>e[i].last&&e[i].last+now<=e[i].end+x) { q.pop(); now-=x-e[i].last; q.push(e[i].last); } } } cout<<ans; } ?
【BZOJ1029】【JSOI2007】【建築搶修】【貪心+堆】