動態規劃演算法學習

2021-10-05 16:23:51 字數 2819 閱讀 4549

7

3 8

8 1 0

2 7 4 4

4 5 2 6 5

在上面的數字三角形中尋找一條從頂部到底邊的路徑,使得路徑_上所經過的數字之和最大。路徑上的每一步都只能往左下或右下走。只需要求出這個最大和即可,不必給出具體路徑。

解決思路是採用遞迴演算法,每個節點只加上,左下和右下兩個資料,即

int x = maxsum(i+1, j);                  // 左下

int y = maxsum(i+1, j+1); // 右下

這樣每一層就會形成兩條分支,直到遞迴到最後一層,求出最大的和,然後退出。

對程式進入maxsum進行計數可以得到一共32次,即2^5

2

52^5

25:是怎麼計算得到的

應該反推這個問題,當第四層到第五層時,一共需要有4∗2

4*24∗

2次,同理第三層到第四層就需要4∗2

∗2

4*2*2

4∗2∗

2,以此類推到第一層4∗2

∗2∗2

4*2*2*2

4∗2∗2∗

2,這就是解決這個問題需要進行的計算次數。

#include #include #include using namespace std;

#define max 101

int d[max][max];

int n;

int max_count = 1;

int maxsum(int i, int j)

int x = maxsum(i+1, j);

int y = maxsum(i+1, j+1);

return max(x, y) + d[i][j];

}int main()

}cout << maxsum(1, 1) << endl;

cout << "max_count:" << max_count << endl;

cout << max_count << endl;

return 0;}/*

輸入:5

73 8

8 1 0

2 7 4 4

4 5 2 6 5

輸出:30

max_count:32

*/

可以看出這種遞迴的做法,程式的執行複雜度還是比較高的當層數遞增的時候,2

n2^n

2n是乙個超大數量級的任務。

從上面我們其實可以發現,中間有大量的重複計算,比如第四層到第五層的7->5這個計算,每次到7的時候都會進行一次計算,就會重複。所以,解決的辦法是,把中間的計算結果儲存下來就好。

把中間結果儲存下來,我們也需要逆向思考,儲存的過程中需要從尾部開始儲存,這樣可以保證計算得到的結果是最大的。

2    7    4    4

4 5 2 6 5

這裡可以儲存第四層的結果,給第三層使用。比如,2+4=6 < 2+5=7 此時在第四層2的位置儲存7就好,第三層遍歷到此處時,可以直接取出7,就避免了重複計算。

這樣的複雜度的計算就會變成加法,第四層到第五層的計算次數,2 * 4 =8 第三層到第四層的計算次數 2 * 3 = 6 ,同理全部的計算次數8 + 6 + 4 + 2=20,計算次數明顯減少,當資料層數增加時,計算的複雜度也僅僅是一加法的形式增加,而不是以次冪的形式增加。

#include #include #include #include #include using namespace std;

#define max 101

int d[max][max];

int maxsum[max][max];

int n;

int max_count = 1;

int maxsum(int i, int j)

if(i == n)

else

return maxsum[i][j];

}int main()

}cout << maxsum(1, 1) << endl;

cout << "max_count:" << max_count << endl;

return 0;

}/*輸出

30max_count:22

*/

把遞迴改為遞推,一般情況下都可以減少程式執行記憶體和執行時間。但是其思想就是剛剛討論的,逆推整個過程,達到冬天解決的目的。我們定義乙個maxsum儲存每一層正確的結果,不需要的就可以拋棄掉。

此時的複雜度計算,是每一層的個數4 + 3 + 2 + 1 = 10,少了遞迴的推進,我們可以不用遞迴到最後一層。

#include #include #include #include #include using namespace std;

#define max 101

int d[max][max];

int *maxsum;

int n;

int max_count = 1;

int main()

}maxsum = d[n];

for(int i = n-1; i >= 1;i--)

}cout << "sum: " 《很多問題都可以用遞迴的方法解決,其思想就是將很大的問題進行分解成很多的小問題,然後解決掉小問題,拼在一起就是整個問題的解決辦法。

當然這僅僅是乙個很小的問題,複雜度較低。回頭我再研究乙個代數方程的例子。

動態規劃演算法

一 動態規劃演算法原理 將待求解的問題分解成若干個相互聯絡的子問題,先求解子問題,然後從這些子問題的解得到原問題的解 對於重複出現的子問題,只在第一次遇到的時候對它進行求解,並把答案儲存起來。了不去求解相同的子問題,引入乙個陣列,把所有子問題的解存於該陣列中,這就是動態規劃所採用的基本方法。動態規劃...

動態規劃演算法

動態規劃 通過把原問題分解為相對簡單的子問題來求解複雜問題。動態規劃常常適用於有重疊子問題和最優子結構性質的問題。演算法總體思想 演算法的基本步驟 演算法的基本要素 最優子結構 重疊子問題 備忘錄方法 問題描述 子串行 公共子串行 最長公共子串行 lcs 問題 問題分析 動態規劃求解lcs問題 最長...

動態規劃演算法

動態規劃演算法的思路 動態規劃法即 dynamic programming method dp 是系統分析中的種常用方法。動態規劃法是20世紀50年代由貝爾曼 r.bellman 等人提出的,用來解決多階段決策過程問題的一種最優化方法。多階段決策過程是指把研究問題分成若干個相互聯絡的階段,由每個階段...