一、概念
動態規劃與分治方法相似,都是通過組合子問題的解來求解原問題。分治方法將問題劃分為互不相交的子問題,遞迴求解子問題,再將它們的解組合起來,求出原問題的解。
動態規劃應用於子問題重疊情況,不同的子問題具有公共的子子問題。這種情況,分治演算法會反覆地求解公共子子問題,動態規劃演算法對每個子問題只求解一次。
動態規劃方法通常用來求解最優化問題。這類問題可以有很多可行解,我們希望尋找具有最優值的解(乙個問題可能有多個最優解)。
設計動態規劃演算法:
刻畫乙個最優解的結構特徵。
遞迴地定義最優解的值。
計算最優解的值,通常採用自底向上的方法。
利用計算出的資訊構造乙個最優解。
二、應用:鋼條切割問題:
問題描述及**
public class cut
// r4 = max(p1 + r3, p2 + r2, p3 + r1, p4)
// 此項公式中,原問題最優解只包含乙個相關子問題(右端剩餘部分)的解,而不是兩個。
private static int cutrod(int p, int n)
int q = -1;
for (int i = 1; i <= n; i ++)
}return q;
}// t(n) 表示第二個引數值為n時,cutrod的呼叫次數
// 如何證明 t(n) = 2 ^ n 注① 下方有證明推導
// 上面的遞迴演算法之所以效率低,是因為反覆求解相同的子問題。
// 動態規劃法:安排求解順序,對每個子問題只求解一次,並將結果儲存下來。如果隨後需要子問題的解,指需查詢儲存的結果,不必反覆計算。
// 1、沿用上面的方法,加入備忘的功能 注② 此方法的執行時間 o(n^2) 下方有說明
private static int memoizedcutrod(int p, int n)
return memoizedcutrodaux(p, n, r);
}private static int memoizedcutrodaux(int p, int n, int r)
if (n == 0) else }}
r[n] = q;
return q;
}// 優化
// 注③ 此方法的執行時間 o(n^2) 下方有說明
// 這種方法一般需要恰當定義子問題「規模」的概念,使得任何子問題的求解都只依賴於「更小的」子問題的求解。
// 因此,我們將子問題按規模排序,由小到大的順序進行求解。當求解莫格仔問題時,它所依賴的更小的子問題都已
// 求解完畢,結果已經儲存。每個子問題都只需求解一次。
private static int bottomupcutrod(int p, int n)
}r[j] = q;
}return r[n];
}public static void main(string args) ;
int value = bottomupcutrod(p, 8);
system.out.println("最大價值:" + value);}}
三種方案時間複雜度分析
注①
t(n) 表示第二個引數值為n時,cutrod的呼叫次數
證明 t(n) = 2 ^ n
注②第二塊**時間複雜度 o(n^2)證明:
第一層 1 to n 還沒遞迴。這個需要執行n次。之後的遞迴 n-1,n-2,…,3,2,1
所以,時間複雜度是o(n^2)
注③第三塊**時間複雜度 o(n^2)證明:
我們可以知道,內層for的執行時間其實是乙個等差數列,
例如:n= 4 時候, 執行次數:1 + 2 + 3 + 4
n = 5 時,執行次數 1 + 2 + 3 + 4 + 5
…所以是 o(n^2)
[1] 概念及題目出處:《演算法導論》 機械工業出版社
演算法與資料結構 動態規劃
動態規劃 dp 的基本思想是 當前子問題的解可由上一子問題的解得出。動態規劃演算法通常基於由乙個遞推公式 狀態轉移方程 和若干個初始狀態 狀態 應用 1 lis longest increasing subsequence 求乙個陣列中的最長非降子串行的長度。子問題 我們可以考慮先求a 0 a 1 ...
演算法與資料結構 動態規劃
用遞迴求解問題時,反覆的巢狀會浪費記憶體。而且更重要的一點是,之前計算的結果無法有效儲存,下一次碰到同乙個問題時還需要再計算一次。例如遞迴求解 fibonacci 數列,假設求第 n 位 從 1 開始 的值,c 如下 include intfib int n return fib n 1 fib n...
資料結構與演算法練習 動態規劃
hz偶爾會拿些專業問題來忽悠那些非計算機專業的同學。今天測試組開完會後,他又發話了 在古老的一維模式識別中,常常需要計算連續子向量的最大和,當向量全為正數的時候,問題很好解決。但是,如果向量中包含負數,是否應該包含某個負數,並期望旁邊的正數會彌補它呢?例如 連續子向量的最大和為8 從第0個開始,到第...