《資料結構與演算法之美》28 動態規劃理論

2022-07-01 18:15:10 字數 2689 閱讀 4639

上一節通過兩個經理案例初步認識動態規劃,今天這一節主要講動態規劃的理論知識。

實際上,動態規劃作為乙個非常成熟的演算法思想,這部分理論總結為「乙個模型三個特徵」。

乙個模型指動態規劃適合解決的問題模型。這個模型定義為「多階段決策最優解模型」。

一般是用動態規劃來解決最優問題。而解決問題的過程,需要經歷多個決策階段。每個決策階段都對應著一組狀態。然後尋找一組決策序列,經過這組決策序列,能夠產生最終期望求解的值。

三個特徵分別是:最優子結構無後效性重複子問題

解決動態規劃問題,一般有兩種思路。分別是狀態轉移表法狀態轉移方程法

狀態轉移表法的解題思路概括為:回溯演算法實現-定義狀態-畫遞迴樹-找重複子問題-畫狀態轉移表-根據遞推關係填表-將填表過程翻譯成**

我們來看一下,如何套用狀態轉移表法來解決動態規劃問題。

假設我們有乙個n乘以n的矩陣w[n][n]。矩陣儲存的都是正整數。棋子起始位置在左上角,終止位置在右下角。那從左上角移動到右下角的最短路徑長度是多少?

// 呼叫方式:mindistbt(0, 0, 0, w, n);

public void mindistbt (int i, int j, int dist, int w, int n)

if (i < n - 1)

if (j < n - 1) }}

從回溯**的函式呼叫可知,每乙個狀態包含三個變數(i, j, dist),其中 i,j 分別表示行和列,dist 表示從起點到達(i, j)的路徑長度。

有了回溯**和狀態定義,把每個狀態作為乙個節點,畫出遞迴樹。

從上圖可知,存在重複子問題。

我們畫出乙個二維狀態表,表中的行、列表示棋子所在的位置,表中的數值表示從起點到這個位置的最短路徑。

按照決策過程,通過不斷狀態遞推演進,將狀態表填好。

狀態轉移方程法的解題思路概括為:找最優子結構-寫狀態轉移方程-將狀態轉移方程翻譯成**

還是拿上面的例子來說明。

min_dist(i, j)可以通過min_dist(i, j-1)和min_dist(i-1, j)兩個狀態推導出來,符合「最優子結構」。

min_dist(i, j) = w[i][j] + min(min_dist(i, j-1), min_dist(i-1, j))

強調一下,狀態轉移方程是解決動態規劃的關鍵

一般情況下,有兩種**實現方法:

用遞迴+「備忘錄」將狀態轉移方程翻譯成**。

public class solution3 , , ,  };

private int n = 4;

private int[, ] mem = new int[4, 4];

public int mindist (int i, int j)

int minup = int.maxvalue;

if (i - 1 >= 0)

int curmindist = matrix[i, j] + math.min (minleft, minup);

mem[i, j] = curmindist;

return curmindist;}}

動態規劃有兩種解題思路:狀態轉移表法和狀態轉移方程法。

狀態轉移表法的解題思路概括為:回溯演算法實現-定義狀態-畫遞迴樹-找重複子問題-畫狀態轉移表-根據遞推關係填表-將填表過程翻譯成**

狀態轉移方程法的解題思路概括為:找最優子結構-寫狀態轉移方程-將狀態轉移方程翻譯成**

演算法與資料結構 動態規劃

動態規劃 dp 的基本思想是 當前子問題的解可由上一子問題的解得出。動態規劃演算法通常基於由乙個遞推公式 狀態轉移方程 和若干個初始狀態 狀態 應用 1 lis longest increasing subsequence 求乙個陣列中的最長非降子串行的長度。子問題 我們可以考慮先求a 0 a 1 ...

演算法與資料結構 動態規劃

用遞迴求解問題時,反覆的巢狀會浪費記憶體。而且更重要的一點是,之前計算的結果無法有效儲存,下一次碰到同乙個問題時還需要再計算一次。例如遞迴求解 fibonacci 數列,假設求第 n 位 從 1 開始 的值,c 如下 include intfib int n return fib n 1 fib n...

資料結構與演算法之美

什麼是資料結構?什麼是演算法 狹義重點 複雜度分析 方法 邊學邊練,適度刷題 複雜度分析 時間複雜度 常見時間複雜度 非多項式量級 非常低效的演算法 空間複雜度 漸進空間複雜度,表示演算法的儲存空間和資料規模的增長關係 最好情況時間複雜度 理想情況的時間複雜度 最壞情況時間複雜度 最糟糕的情況下的時...