基本思想是將待求解問題分解成若干子問題,先求解 子問題,最後用這些子問題帶到原問題,與分治算法的不同是,經分解得到的子問題往往是不是相互獨立,若用分治則子問題太多。
2、適用動態規劃算法問題的特徵
a、優化原則。具有最優的子問題.或者說一個最優決策序列的任何子序列本身一定是相對於子序列的初始和結 束狀態的最優的決策序列。
b、子問題重疊性質。一般情況是子問題不能獨立,需要多次計算。
a、將問題表示成多步判斷。
b、確定是否滿足優化原則,確定子問題的重疊性。
c、列出關於優化函數的遞推方程(或不等式)和邊界條件。
d、自底向上計算子問題的優化函數值。
e、備忘錄方法記錄中間結果。在算法實現上是從低往上的,這點和分治算法不同。
f、標記函數追蹤問題的解。
4、舉例
投資問題:
m元錢,n項投資,fi(x): 將x元投入第i項項目的效益,
目標函數max {f1(x1) + f2(x2) + … + fn(xn) }
約束條件x1 + x2 + … + xn = m,xi ∈ N
設Fk(x) 表示x元錢投給前k個項目的最大效益
多步判斷: 假設知道p元錢(p≤x)投給前k −1個項目的最大效益,決定x元錢投給前k個項目的分配方案
遞推方程和邊界條件:
Fk(x) = max{fk(xk)+Fk-1(x-xk)}
F1(x)=f1(x)
算法實現
投資第k個項目p元錢的效益可表示爲Project[k][p],其中0<=k<=n,0<=p<=m;設投資給前k個項目p元 錢的最終總效益爲用Benefit[k][p],其中0<=k<=n,0<=p<=m。設allot[k][p]表示在總投資爲p元錢時候,最終分配給第k個項目的錢數解。
算法如下:
for(k=0 ; k<= n ;i++)
{
for(p=0 ; p<= m ;p++) //開始從低往上計算k個項目、總投資爲p元情況下的效益
{
Benefit[k][p] = 0;
allot[k][p] = 0;
for(x=0; x<=p ;x++) //遍歷p元錢分配情況:x和p-x,取出一個最大值
{
if( Benefit[k][p]<( Benefit[k-1][x] + project[k][p-x]))
{
Benefit[k][p] = Benefit[k-1][x] + project[k][p-x];
allot[k][p] = x;
}
}
}
}
最後方便得出效益:Project[k][p],
其中allot[1][p]、allot[2][p].....allot[k][p]便是對應的項目解,也就是投資給每個項目的錢數。
算法分析:w(n)=O(nm2),算法需要較大的輔助空間。