動態規劃(dynamic programming) 是個較難理解的演算法,常用於最佳化問題的求解。和分治法類似,動態規劃也是解決小問題的基礎上合并為更大規模的解。動態規劃中,一個大問題的一個最優解必定包含子問題的最優解;且這些子問題是重疊的。為免子問題重複計算,通常將子問題的最優解儲存在一個表中。並且,後續問題的解必須不會影響之前子問題的最優解(無後效性)。 設計一個動態規划算法有以下步驟: step1: 刻畫最優解結構 step2:: 遞迴定義最優解的值 step3: 自底向上計算最優解的值 step4: 由計算出的值構造一個最優解。動態規劃的數學分析太複雜,下面用一些例子說明。 問題1: 求一個序列Ai的一個最大上升子序列長度(可能有多個)。如序列5,3,4,8,6,7 的其中一個最大上升子序列為3,4,6,7 。分析:設狀態i是以A[i]為結尾字元的最大上升子序列。用S[i]記錄從A[1]~A[i]的最大子序列長度,例如S[3] =2 。可知僅當j<i 時S[j] < S[i], S[i] <-- S[j]+1 , 定義最優解的值if ( S[j] < S[i] )S[i] <-- max (S[j]) + 1 (對j < i)elseS[i] <-- max(S[j])可以看出,S[i]可以直接利用前一個數(i-1)的最優值。if (S[i] < S[i-1] ) S[i] < S[i-1] + 1else S[i] = S[i] – 1 得主S序列: 1, 1, 2, 3, 3, 4, 最後得出最長子序列長度為4 太累,實在寫不下去了………… 問題2: 求有向加權圖的最短路徑,我們知道可以用Dijkstra演算法求解,這也是個動態規劃問題。問題3: 矩陣乘法鏈問題。一串矩陣連乘A1A2A3A4... ,我們知道矩陣相乘符合結合律,例如可以這樣算 (A1A2)* (A3A4) 不同的相乘順序所需的運算時間可以差很遠。為找出最佳的運算括弧組合,也可以用動態規劃求解。問題4: 0/1背包問題。有n種物品,重量分別為wi, 價格分別為pi, 容量把他們裝入載重容量為c的背包,如何裝入使得總價格最大。