采用動態規劃發求解的問題必須具有兩個性質:最優子結構和子問題重疊。
動態規劃算法的基本要素
(1)最優子結構:當問題的最優解包含了其子問題的最優解時,稱該問題具有最優子結構性質。
(2)重疊子問題:在用遞歸算法自頂向下解問題時,每次產生的子問題并不總是新問題,有些子問題被反復計算多次。這種性質稱為子問題的重疊性質
與分治法相同,動態規劃法具有最優子結構性質。動態規劃法的解決辦法,也是將一個大問題分解為若干個規模較小的子問題,通過合并求解的子問題而得到原問題的解。
與分治法不同,動態規劃法的子問題重疊,指分解出的子問題不是相互獨立的,有重疊部分。如果采用分治法求解,重疊的子問題將被重復計算多次。
動態規劃法采用備忘錄做法解決子問題重疊。對每個子問題只求解一次,保存每個子問題的計算結果,就像一個備忘錄,當需要再次求解某個子問題是,只要查找備忘錄中的結果即可,要求備忘錄的查找時間為常數。
動態規劃求解步驟:
(1)找出最優解的性質,并刻畫其結構特征。
(2)遞歸地定義最優值(寫出狀態轉移方程,或稱動態規劃方程)。
(3)以自底向上(或自頂向下)的方式計算出最優值。
(4)根據計算最優值時得到的信息,構造一個最優解。
f(n,m)=max{f(n-1,m), f(n-1,m-w[n])+P(n,m)}
動態規劃算法基本框架代碼
for(j=1; j<=m; j=j+1) // 第一個階段
xn[j] = 初始值;
for(i=n-1; i>=1; i=i-1)// 其他n-1個階段
for(j=1; j>=f(i); j=j+1)//f(i)與i有關的表達式
xi[j]=j=max(或min){g(xi-1[j1:j2]), ......, g(xi-1[jk:jk+1])};
t = g(x1[j1:j2]); // 由子問題的最優解求解整個問題的最優解的方案
print(x1[j1]);
for(i=2; i<=n-1; i=i+1)
{
t = t-xi-1[ji];
for(j=1; j>=f(i); j=j+1)
if(t=xi[ji])
break;
}