各種瞎寫
之後也不知道為什麼就過了
剛看到這道題感覺確實是不會的,因為我貪心太差了\(qaq\)
之後就隨便\(yy\)唄
發現首先我們得排一下序,以\(t2\)也就是建築的損壞時間為第一關鍵字從小到大排序
這個還是比較好考慮的,我們得優先照顧一下那些在最開始就會損壞的建築
那之後呢,好像我們現在可以做乙個\(dp\)了
我們設\(dp[i][j]\)表示在前\(i\)個裡選擇\(j\)個的最小時間是多少
這個\(dp\)的狀態數就是\(n^2\)的,儘管我們可以\(o(1)\)轉移,但是還是炸了
我們考慮一下貪心
我們還是按照剛才的排序來考慮
顯然這樣直接按照排出來的順序掃一遍是不行的,我們得給前面的選擇乙個反悔的機會
於是我們開乙個大根堆,用來儲存之前選擇的那些建築的修築時間
我們一旦新插入乙個建築,如果這個建築可以被修築,也就是\(t1_i+tot<=t2_i\),\(tot\)表示之前所選取的建築的總時間和,那麼我們就讓這個建築被修建
否則的話,我們把這個建築和堆頂比較一下,看一看能否用這個元素取代堆頂,使得再刪除堆頂的情況下這個建築能否被選上,能的話就選上,否則就不選
至於這樣為什麼對呢,每乙個建築的價值都是\(1\),所以對於第二種情況來說它入堆的話就必須保證這個建築能被選上且讓這個建築在被選上的情況下總時間最短,否則就還不如不選這個建築
**
#include#include#include#include#include#define ll long long
#define re register
#define maxn 150005
#define max(a,b) ((a)>(b)?(a):(b))
struct node
a[maxn];
std::priority_queueq;
inline int cmp(node k,node m)
int n;
int now=0,ans=0;
int main()
else
}} std::cout
}
JSOI2007 建築搶修
提交傳送門 這個就是乙個貪心唄,用set維護大到小的數列 然後如果能搶修乙個建築的話就ans 不能的話,看看比不比上一次搶修的優秀,優秀的話就選它,然後更換 description 小剛在玩jsoi提供的乙個稱之為 建築搶修 的電腦遊戲 經過了一場激烈的戰鬥,t部落消滅了所有z部落的入侵者。但是t部...
JSOI2007 建築搶修
小剛在玩jsoi提供的乙個稱之為 建築搶修 的電腦遊戲 經過了一場激烈的戰鬥,t部落消滅了所有z部落的入侵者。但是t部落的基地裡已經有n個建築設施受到了嚴重的損傷,如果不盡快修復的話,這些建築設施將會完全 毀壞。現在的情況是 t部落基地裡只有乙個修理工人,雖然他能瞬間到達任何乙個建築,但是修復每個建...
JSOI2007 建築搶修
開始以為是按照修建時間短的排序,先把修建時間短的修了。但是這樣顯然有問題,因為可能前面的倒塌時間靠後,你先修了,後面塌的就不能修了。所以要按倒塌時間排序開始修。然後如果當前的建築物來得及修,當然是要修的。這時候我們維護乙個已經修過的建築物的大根堆 優先佇列 如果不能修,看看是否從原先修建過的建築物中...