動態規劃如何輸出路徑?
動態規劃的大部分題目 都是不需要輸出具體的路徑的,但是萬一要輸出路徑呢?
下面來看一下動態規劃如何輸出路徑,以揹包問題為例:
一般而言,揹包問題是要求一個最優值,
如果要求輸出這個最優值的方案(路徑),可以參照一般動態規劃問題輸出方案的方法:記錄下每個狀態的最優值是由狀態轉移方程的哪一項推出來的,換句話說,記錄下它是由哪一個策略推出來的。便可根據這條策略找到上一個狀態,從上一個狀態接著向前推即可。
這也就意味著 我們必須要維護一個狀態陣列 這個陣列和DP陣列一樣,每個元素必須記錄著這個狀態是由哪個元素轉移過來的。也就是說 我們要知道我們選擇當前的座標 是由哪個座標跳過來的。所以我們在每個點就存上一個點的座標。
或者我們選擇哪個就把哪個座標點標記為1 如果我們並不決定要走那個點 就把其重新覆蓋為0.
輸出字典序最小的最優方案:這樣的話 跟我們選擇的順序有關係 --感覺這就完全改變了這個問題。解決方案並沒有看懂
求次優解/第K優解: 我們的思路還是動態規劃 狀態轉移方程也沒有變化。唯一有變化是 針對每個點 我們不是隻存一個當前最優值 而是存所有的可能的值(其實也不是所有可能的值 而是最大或者最小的k個值(至於為什麼這樣 見附錄的解釋)),將之放進PQ裡面,每次要每個狀態都試一遍。最後在陣列的最後 輸出PQ種poll出來的第K個元素即可。
附錄:
為什麼我們合併兩個序列a b
假設第一個序列長為m 第二個為n
我們只需要取第一個序列前k個和第二個序列的前k個
合併得到的長度為2k的序列 這個序列一定包含a+b的前k個最大的元素。
為什麼呢?
假設
a = [a1 a2 a3 a4 a5] 從大到小
b = [b1 b2 b3 b4 b5] 從大到小
k=3
我們取a的前三個和b的前3個 這六個元素一面一定包含 [a1 a2 a3 a4 a5 b1 b2 b3 b4 b5] (亂序)的前k大的元素。
證明:
[b1 + a1, b1 + a2, b1 + a3]就已經比[b1 + a4]大了 所以已經存在k個比b1+a4大的了 所以這個組合肯定沒有機會進入前K大。所以每個取前k個就足夠了。
refer:
dd大牛的揹包九講-揹包問題彙總
相關文章
- 動態規劃之最短路徑和動態規劃
- 動態規劃動態規劃
- [leetcode] 動態規劃(Ⅰ)LeetCode動態規劃
- 動態規劃法動態規劃
- 模板 - 動態規劃動態規劃
- 動態規劃初步動態規劃
- 動態規劃分析動態規劃
- 動態規劃(DP)動態規劃
- 動態規劃--三角形最小路徑和動態規劃
- 演算法系列-動態規劃(1):初識動態規劃演算法動態規劃
- 【動態規劃】用一維和二維解決不同路徑動態規劃
- java 動態規劃(三角形最短路徑和)Java動態規劃
- 動態規劃小結動態規劃
- [leetcode 1235] [動態規劃]LeetCode動態規劃
- 動態規劃專題動態規劃
- 動態規劃-----線性動態規劃
- 好題——動態規劃動態規劃
- 動態規劃初級動態規劃
- 淺談動態規劃動態規劃
- 3.動態規劃動態規劃
- 動態規劃題單動態規劃
- 動態規劃 總結動態規劃
- 雙序列動態規劃動態規劃
- 動態規劃方法論動態規劃
- [atcoder 358] 【動態規劃】動態規劃
- 區間動態規劃動態規劃
- 動態規劃(Dynamic programming)動態規劃
- 有關動態規劃動態規劃
- 路徑規劃: 淺談路徑規劃演算法演算法
- 動態規劃之數的劃分動態規劃
- [動態規劃] 五、三角形的最小路徑和動態規劃
- 禮物的最大價值(一維動態規劃&二維動態規劃)動態規劃
- leetcode題解(動態規劃)LeetCode動態規劃
- [動態規劃] 區間 dp動態規劃
- (C++)DP動態規劃C++動態規劃
- 【CodeChef】Graph Cost(動態規劃)動態規劃
- leetcode總結——動態規劃LeetCode動態規劃
- 動態規劃練習題動態規劃