JSOI2007 建築搶修

2022-08-13 15:42:12 字數 1652 閱讀 8576

小剛在玩jsoi提供的乙個稱之為「建築搶修」的電腦遊戲:經過了一場激烈的戰鬥,t部落消滅了所有z部落的入侵者。但是t部落的基地裡已經有n個建築設施受到了嚴重的損傷,如果不盡快修復的話,這些建築設施將會完全毀壞。現在的情況是:t部落基地裡只有乙個修理工人,雖然他能瞬間到達任何乙個建築,但是修復每個建築都需要一定的時間。同時,修理工人修理完乙個建築才能修理下乙個建築,不能同時修理多個建築。如果某個建築在一段時間之內沒有完全修理完畢,這個建築就報廢了。你的任務是幫小剛合理的制訂乙個修理順序,以搶修盡可能多的建築。

第一行是乙個整數n,接下來n行每行兩個整數t1,t2描述乙個建築:修理這個建築需要t1秒,如果在t2秒之內還沒有修理完成,這個建築就報廢了。

輸出乙個整數s,表示最多可以搶修s個建築.

4

100 200

200 1300

1000 1250

2000 3200

n < 150,000; t1 < t2 < maxlongint

堆 + 貪心

題目給了兩個限制條件

乙個是修建時間

另乙個是最晚修建期限

顯然兩個關鍵字不能貪心

所以我們想辦法消除乙個關鍵字

按照最晚修建期限從小到大排序!

這樣就可以保證後面處理的建築可以隨意替代前面修建的任意乙個建築

我們就可以開個堆貪心了

按照時間花費維護乙個大根堆

再維護乙個endtime表示修建完前面的建築後的時間

然後我們就對於乙個建築

盡量早修理

如果\(end[i] - cost[i] < endtime\) 說明目前這種方案是不能修理這個建築的

這時我們就要從大根堆中拿出cost最大的元素x

如果 \(cost[x] < cost[i]\) 那就不修這個建築了

否則就用這個建築去代替x那個建築

因為我們已經按照end排序了

所以之前的建築的end一定小於當前建築的end

直接替代並把endtime減去兩者的修築時間差\((cost[x] - cost[i])\)即可

#include#include#include#include#includeconst int m = 150005 ;

using namespace std ;

inline int read()

while(c>='0'&&c<='9')

return x*w ;

}int n , ans , endtime ;

struct building p[m] ;

struct node ;

priority_queue < node > q ;

inline bool operator < (building a , building b)

inline bool operator < (node a , node b)

int main() ) ;

++ ans ;

}else if(!q.empty()) ) ;}}

}printf("%d\n",ans) ;

return 0 ;

}

JSOI2007 建築搶修

提交傳送門 這個就是乙個貪心唄,用set維護大到小的數列 然後如果能搶修乙個建築的話就ans 不能的話,看看比不比上一次搶修的優秀,優秀的話就選它,然後更換 description 小剛在玩jsoi提供的乙個稱之為 建築搶修 的電腦遊戲 經過了一場激烈的戰鬥,t部落消滅了所有z部落的入侵者。但是t部...

JSOI2007 建築搶修

小剛在玩jsoi提供的乙個稱之為 建築搶修 的電腦遊戲 經過了一場激烈的戰鬥,t部落消滅了所有z部落的入侵者。但是t部落的基地裡已經有n個建築設施受到了嚴重的損傷,如果不盡快修復的話,這些建築設施將會完全 毀壞。現在的情況是 t部落基地裡只有乙個修理工人,雖然他能瞬間到達任何乙個建築,但是修復每個建...

JSOI2007 建築搶修

開始以為是按照修建時間短的排序,先把修建時間短的修了。但是這樣顯然有問題,因為可能前面的倒塌時間靠後,你先修了,後面塌的就不能修了。所以要按倒塌時間排序開始修。然後如果當前的建築物來得及修,當然是要修的。這時候我們維護乙個已經修過的建築物的大根堆 優先佇列 如果不能修,看看是否從原先修建過的建築物中...