什麼是動態規劃
的思想就是將大問題拆分成小問題進行攻破;
比如鋼條切割問題:
給定一段長度為n的鋼條和如下的價格表,求切割鋼條方案,使得收益最大

我們很容易想到通過遞迴進行求解:
假設price(x)代表長度x的鋼材的最大收益,我們很容易將問題進行遞迴分解:
price(n) = max(pi, price(1)+price(n-1), price(2)+price(n-2),....,price(n-1)+price(1) ); 複製程式碼
比如,我們求解一根長度為4的鋼材的切割方式:
就是求取各種組合的最大利益
price(4) = max(p4, price(1) + price(3), price(2) + price(2), price(3) + price(1)); 複製程式碼
那麼接下來就是求解,price(3)、price(2)、price(1)的問題了;
這種自頂向下分解遞迴的方式肯定是可以解決這個鋼條切割的問題的,但是有沒有缺陷?
有的,還不小,就是效率問題。
隨著x的增大,遞迴的效率會越來越低,執行速度會很慢,因為什麼?
因為它在反覆求解相同的問題 在price(3)時,其已經計算過3的最優解了,且2、1的肯定也有了; 作為人類,我們自然而然就會將這個結果記住,並用於下次計算; 但是遞迴不會,在price(4)的時候,其仍然還會計算price(3),price(2),price(1),不管是不是上次遞迴已經計算過了。 複製程式碼
那麼解決這個問題的很簡單的辦法是什麼?
沒錯,就是 將先前解決的子問題,進行儲存,以減少重複計算! 這就是
好了,貌似我們討論到現在都是說的遞迴問題,其實呢,到目前為止,我們已經講完了動態規劃的本質:
2. 什麼是動態規劃
1.動態規劃是通過組合子問題的解來解決原問題 2.動態規劃應用於子問題重疊的情況,即不同的子問題具有公共的子子問題 3.動態規劃演算法對每個子子問題只求解一次 4.動態規劃通常用來求解最優化問題 複製程式碼
動態規劃演算法:
1.刻畫一個最優解的結構特徵 2.遞迴的定義最優解的值 3.計算最優解的值,通常自底向上 4.利用計算出的資訊構造一個最優解 複製程式碼
好了,讓我們用動態規劃解一下鋼條切割問題:
1.刻畫一個最優解的結構特徵遞迴法中已經刻畫的很清楚了
2.遞迴的定義最優解的值公式也在上面寫過了
通過帶備忘的自頂向下遞迴法,我們成功的比較高效的解決了鋼鐵切割的問題,這也是動態規劃的一種方式,有沒有其他方式?
有的,對應於自頂而下,我們採用自底而上的方式,將子問題按照從小到大的順序進行求解,當然還是得有備忘機制。
大部分情況下,自頂而下和自底而上的效率是近似的;但是呢,在某些特殊情況,自頂向下方法並未真正的遞迴考察所有可能的子問題;而且自底向上也沒有頻繁的遞迴函式的開銷;
所以,一般動態規劃都是採用自底向上的方法,將複雜的問題,變成了簡單的多項式相加。
4.利用計算出的資訊構造一個最優解這條就更簡單了,既然你演算法都寫出來了,在演算法的途中,加上最優解的儲存及輸出就可以了,
比如動態規劃鋼鐵切割問題,在演算法最初,我們關心的是price(n),計算出最佳的收益; 最後我們只要在編寫出的演算法中,加上輸出鋼鐵的分割就可以了。 複製程式碼
3. 典型的動態規劃
鋼鐵切割問題本身就是個典型的動態規劃,除了這個例子,還有:
最長公共子序列 最優二叉搜尋樹 矩陣鏈乘法 .... 複製程式碼
不管是什麼問題,本質上我們都是通過層層分解子問題,並進行組合;
如果這個問題,滿足上述特性,那麼動態規劃就是這些問題可能的解決方法之一。
某些問題是否適用於動態規劃演算法,你可以從如下角度:
1.是否具有最優子結構性質 如果一個問題的最優解,包含其子問題的最優解 2.具有重疊子問題性質 問題的遞迴演算法會反覆求解相同的子問題 複製程式碼
演算法的精髓在於,其沒有最好,只有最合適
其他相關章節 複製程式碼