步驟
1,滿足dp演算法的必要條件:最優子結構
2,定義遞迴函式, <-- 這步是關鍵,
3,自底向上計算遞迴函式
4,從計算過程儲存的資訊中,構造最優解的細節
很多實際問題需要從所有可能的情況中找出所需要的情況,有時這沒有公式,唯一的辦法是搜尋、窮舉,而隨著問題規模擴大,單純的窮舉耗費問題規模的指數時間,對於大規模的問題,即使用計算機解決也很不可取。當問題具有最優子結構時,相同的子問題只需要計算一次,在自底向上的求最優解過程中,僅有子問題就能在可接受的時間複雜度內,計算出更接近最終最優解的子問題,最終完成最優解的計算。動態規劃演算法的這個特點:對子問題只計算一次,可以看做對窮舉演算法的乙個很有效的剪枝。使得演算法時間複雜度有很大很進。dp的自底向上計算過程是對最優子結構的運用:新問題被分解成一系列子問題,這些子問題的最優解都已求出,這時新問題的最優解面臨一系列選擇,從這一系列選擇中構造新問題的最優解,依次類推以新問題為子問題構造更新的問題,直至原問題的最優解。這就是dynamic programming。
舉例備忘
描述:
在二維座標上給n個點(n是偶數)的座標,座標都是整數,可以任意聯接其中兩點(不管中間有沒有障礙),這兩點就消失了(和遊戲裡的一樣).但消去兩點的路徑和兩個點的位置有關,也就是說路徑的長度等於兩點x軸與y軸差的絕對值之和.比如乙個點座標為(10,10),另外乙個點座標為(2,3),那麼消去這兩個點的路徑長度為8+7=15.問消去所有點的路徑長度之和最小值是多少?
動態規劃解法:
輸入點對 p1, p2, p3, ... , pn 。座標(x, y),點對的和表示為: distance(i,j) = | pi.x - pj.x | + | pi.y - pj.y | ,求點對序列s:(s1,s2), (s3,s4), ... , (sn-1, sn),使得 distance(s1,s2) + distance(s3,s4) + ... + distance(sn-1,sn)最小, 1 <= s1, s2, ..., sn <= n。
1,最優子結構顯而易見,從最優解中任意剔除一對點,得到的點對也是剩餘的點的最優解。
2,遞迴函式:
遞迴函式s(len, i, j)定義為:從對點長度為len對 ,且所有點對中不包含點pi,pj時,可以找到的所有的len對點對序列中最小長度和的點對序列。 1 <= len <= n / 2,1 <= i, j <= n;
e(len, i, j, k),表示某個最優解為s(len, i, j)的子問題中是否含有pk,用0代表s(len, i, j)包含pk, 1代表不包含。
那麼,已知所有點對長度為len - 1的s(len - 1, i, j)時(對給定長度len,s共有n(n-1)/2種),求一新問題s(len,i,j)的最小值時,假定新問題包括某一點對(k,l),考慮下面兩種情況:
1,如果s(len-1,k,l)不包括i和j,那麼如果包含點k,l的s(len,i,j)最小值肯定是等於s(len-1,k,l)+d(k,l),因為s(len-1,k,l)的定義就是長度為len-1且不包括(k,l)的子問題最優解。
2,如果s(len-1,k,l)包含了i,j,s(len, i, j)仍然可能包含點k,l,因此這種情況下不應該捨棄點k,l,而應該在長度為len-1的所有(n^2/2-n)個子問題s(len-1,x,y)中選擇乙個不包含點k,l和點i,j的子問題s(len-1,sub_i,sub_j),由s(len-1,sub_i,sub_j)+d(k,l)構成s(len, i, j)。
從上訴兩種情況中,得出s(len,i,j),即:從所有(k,l)點對假設中得到的一系列s(len,i,j)的最小值。
綜合以上分析,得到遞迴函式s和e:
s(len, i, j) = min + d(k, l) : 所有非i, j的點k, l
} = s(len - 1, sub_i, sub_j) + d(new_i, new_j)
s式中對點的包含關係用e陣列來記錄,e陣列也遞迴計算:
e(len, i, j, k) = e(len - 1, sub_i, sub_j, k)(k為變數), 且 e(len, i, j, new_i) = 0 且 e(len, i, j, new_j) = 0
s式和e式就是該問題的乙個dp解法的遞迴函式。
直覺上,s陣列代表共有n^3/2個子問題,每個子問題由(n^2/2-n)個(k,l)假設計算得到,每個(k,l)假設)要考慮所有len-1的(n^2/2 - n)個子問題s(len-1, x, y),所以t = o(n^7)
剩下的3,4步驟已經很容易
複雜度: 時間7次方,空間4次方 !!!!!!!!!!!!!!!
實現:
動態規劃演算法
一 動態規劃演算法原理 將待求解的問題分解成若干個相互聯絡的子問題,先求解子問題,然後從這些子問題的解得到原問題的解 對於重複出現的子問題,只在第一次遇到的時候對它進行求解,並把答案儲存起來。了不去求解相同的子問題,引入乙個陣列,把所有子問題的解存於該陣列中,這就是動態規劃所採用的基本方法。動態規劃...
動態規劃演算法
動態規劃 通過把原問題分解為相對簡單的子問題來求解複雜問題。動態規劃常常適用於有重疊子問題和最優子結構性質的問題。演算法總體思想 演算法的基本步驟 演算法的基本要素 最優子結構 重疊子問題 備忘錄方法 問題描述 子串行 公共子串行 最長公共子串行 lcs 問題 問題分析 動態規劃求解lcs問題 最長...
動態規劃演算法
動態規劃演算法的思路 動態規劃法即 dynamic programming method dp 是系統分析中的種常用方法。動態規劃法是20世紀50年代由貝爾曼 r.bellman 等人提出的,用來解決多階段決策過程問題的一種最優化方法。多階段決策過程是指把研究問題分成若干個相互聯絡的階段,由每個階段...