小剛在玩jsoi提供的乙個稱之為「建築搶修」的電腦遊戲:經過了一場激烈的戰鬥,t部落消滅了所有z部落的入侵者。但是t部落的基地裡已經有n個建築設施受到了嚴重的損傷,如果不盡快修復的話,這些建築設施將會完全毀壞。現在的情況是:t部落基地裡只有乙個修理工人,雖然他能瞬間到達任何乙個建築,但是修復每個建築都需要一定的時間。同時,修理工人修理完乙個建築才能修理下乙個建築,不能同時修理多個建築。如果某個建築在一段時間之內沒有完全修理完畢,這個建築就報廢了。你的任務是幫小剛合理的制訂乙個修理順序,以搶修盡可能多的建築。
輸入格式:
第一行是乙個整數n,接下來n行每行兩個整數t1,t2描述乙個建築:修理這個建築需要t1秒,如果在t2秒之內還沒有修理完成,這個建築就報廢了。
輸出格式:
輸出乙個整數s,表示最多可以搶修s個建築.
輸入樣例#1:
4100 200
200 1300
1000 1250
2000 3200
輸出樣例#1:
3
n < 150,000; t1 < t2 < maxlongint
solution:
本題很顯然貪心。
開始時我按修的時間從小到大排序,然後能修就修,不能就和上乙個答案比較一下能不能使總時間變得更短且滿足當前這乙個的時間限制。
果然,第一遍思路總是錯的$wa$了$6$個點。
然後,想到修建所需時間沒有什麼用,先修後修都無所謂關鍵是不超過限制時間,所以總時間越短,更利於滿足限制條件,於是應該是按限制時間從小到大排序。
那麼,排序後還是能修就修,否則就和前面修過的所有建築中時間最大的比較一下,看能否替換使總時間變小且滿足當前這個的時間限制,替換後雖然不會使得答案變大,但能讓總時間減小,使後面選擇時滿足時間限制的機率變大。那麼所有修過的建築所需時間用乙個大根堆維護一下,就$ok$了。
**:
#include#define for(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)#define max(a,b) ((a)>(b)?(a):(b))
using
namespace
std;
const
int n=150005
;int
n,ans,all;
struct
node
}a[n];
priority_queue
q;inline
intgi()
intmain()
else}}
cout
}
P4053 JSOI2007 建築搶修
miku 貪心按照時間從前往後盡可能的修 如果能修就修,修不了的話 我們可以選擇撤掉乙個以前修的騰出時間來,但是,騰出兩個顯然更蠢 那麼,顯然無論騰不騰,截止到此建築,能修的數量最多一定 由此觀之,應該把已修的最大的取出來,然後進行比較,放進小的,扔掉大的,來為後面騰時間 include inclu...
P4053 JSOI2007 建築搶修
傳送門 看題目就想到 dp 想不出來就去想貪心.考慮按右端點排序,乙個個修,如果在修某個建築 i 時發現來不及了,說明前 i 個建築最多只能修 i 1 個 那麼我們把前 i 個中耗時最長的那個放棄,這樣省下的時間最多 然後用優先佇列維護一下就行 include include include inc...
洛谷P4053 JSOI2007 建築搶修
小剛在玩jsoi提供的乙個稱之為 建築搶修 的電腦遊戲 經過了一場激烈的戰鬥,t部落消滅了所有z部落的入侵者。但是t部落的基地裡已經有n個建築設施受到了嚴重的損傷,如果不盡快修復的話,這些建築設施將會完全毀壞。現在的情況是 t部落基地裡只有乙個修理工人,雖然他能瞬間到達任何乙個建築,但是修復每個建築...