筆記 演算法基礎 延遲決策的貪心問題

2022-03-05 16:05:11 字數 1902 閱讀 7890

這一類的問題的共同特點是收到了乙個名額之後不急著把名額用出去,先保留著名額,當後面遍歷到不可抗力因素時把再把最差的若干個名額丟棄。注意有時候同乙個名額可能多次收到,有可能以最後一次收到時為準(當然也可以多次出入隊,不過這樣要在出隊時判斷是否是一次有效的出隊)。

還有ccpc的摸魚大師那題啥時候去補一下。

題意:你要去征服直線上的按順序的n個城堡,征服第i個城堡需要擁有至少ai個戰士(只是需要擁有,並不會消耗),占領完成之後會獲得bi個戰士。你可以留下乙個戰士來駐守城堡,駐守會獲得ci的得分。有兩種方式駐守:你在i點,那麼可以派人駐守i點;或者你在u點,u->v有傳送門,那麼你可以派人駐守v點。傳送門只會通向前面的城堡。不能走回頭路,假如未能占領完則輸掉。求最大的得分,注意在占領完n號城堡後也可以進行駐守和使用n點的傳送門。

題解:連題意都暗示要貪心?看起來很像ccpc網路賽的摸魚宗師那道題。首先全部不進行駐守強行占領看看是不是有解。然後每一步都會有乙個多餘值,多餘值的最小值就是可以拿去派的,派給全域性得分最高的城堡就行了。然後全場的多餘值都下降了,會有某個碰到了0,假如最後乙個碰到0的城堡後面的城堡還有多餘值,那麼可以派給這一段城堡能夠連向的地方的最高得分。也就是每次是詢問乙個包含結尾的城堡集及其傳送門包含的城堡集裡面的最大值。

那麼每打乙個城堡就把兵留下來並盡可能派往傳送門,然後把這些兵放進小根堆裡面等待召回,假如需要更多兵的時候就要召回他並清除城堡的得分及占領標記。注意到每個城堡最多收回5000個兵然後派出5000個兵,只有5000個城堡,再套個log就比較**。

但是這個演算法很有問題,打了補丁也還是很有問題,問題在於每次貪心取城堡,但是有時候把好的城堡空出來給後面的傳送門拿更優。

就算不急著把城堡拿去駐守,那麼在士兵不夠用的情況肯定要去除一部分駐守的名額,要去除哪些呢?去除最小的顯然不對,因為去除大的也有可能後面會有機會重新派過去駐守而那時候有空閒的士兵。發現乙個很顯然的貪心,派去駐守同乙個城堡的時間越靠後越好,所以每個城堡實際上只有最後的指向它的傳送門有效。在那個傳送門時假如沒有空閒的士兵就再也沒有機會了。但是我們可以先保持這個城堡的名額,只有當人手不夠的時候才會有城堡因為價值最小且目前持有的城堡以後都沒有辦法再駐守而被淘汰。反向遍歷可以計算出每個點時空閒的士兵的數量,會發現其實過了某些險峻的關卡只會空閒度會突然上公升。

int a[5005], b[5005], c[5005];

int prefixb[5005], dif[5005];

int from[5005];

vectorto[5005];

priority_queue, greater>pq;

void test_case()

for(int i = 1, u, v; i <= m; ++i)

for(int i = 1; i <= n; ++i)

to[from[i]].push_back(i);

for(int i = 1; i <= n; ++i)

for(int i = n - 1; i >= 1; --i)

dif[i] = min(dif[i], dif[i + 1]);

if(dif[1] < 0)

for(int i = 1; i <= n; ++i) );

while(pq.size() > dif[i])

pq.pop();

}int sum = 0;

while(pq.size())

printf("%d\n", sum);

}

總結:這類問題不是要拿到城堡的時候立刻按照價值貪心,因為後面有可能會重新更新大的城堡所以有可能現在去除大的城堡更優。先觀察出是只有最後一次機會派往城堡時才需要把他派出去,在這之前肯定是帶著士兵一起走最好。就算拿到了派往城堡的名額也不是立刻把士兵派過去,是保留派過去的資格直到因為某種原因失去資格。在這裡失去資格的原因是因為某個時刻下城堡數嚴格多於後面要用到的最少的士兵數,就選擇最差的城堡淘汰掉。

演算法筆記 簡單貪心(月餅問題)

貪心法是求解一類最優問題的方法,它總是考慮當前狀態下區域性最優 或較優 的策略,來使全域性的結果達到最優 或較優 顯然,如果採取較優而非最優的策略 最優策略可能不存在或是不易想到 得到的全域性結果也無法是最優的。而要獲得最優結果,則要求中間的每步策略都是最優的,因此嚴謹使用貪心法來求解最優化問題需要...

nyoj47 過河問題(貪心演算法) 演算法筆記

題目描述 在漆黑的夜裡,n位旅行者來到了一座狹窄而且沒有護欄的橋邊。如果不借助手電筒的話,大家是無論如何也不敢過橋去的。不幸的是,n個人一共只帶了乙隻手電筒,而橋窄得只夠讓兩個人同時過。如果各自單獨過橋的話,n人所需要的時間已知 而如果兩人同時過橋,所需要的時間就是走得比較慢的那個人單獨行動時所需的...

貪心演算法解決跳馬問題 貪心演算法及解決的問題 10

貪心演算法是一種在每一步選擇中都採取在當前狀態下最好或最優 即最有利 的選擇,從而希望導致結果是全域性最好或最優的演算法。貪心演算法與動態規劃的不同在於它對每個子問題的解決方案都做出選擇,不能回退。動態規劃會儲存以前的運算結果,並根據以前的結果對當前進行選擇,有回退功能。貪心法可以解決一些最優化問題...