演算法學習 動態規劃實踐

2021-08-13 16:35:52 字數 1725 閱讀 3368

完成日期:2017.10.26

1. 實踐題目

數字三角形

2. 問題描述

給定乙個由 n行數字組成的數字三角形如下圖所示。試設計乙個演算法,計算出從三角形 的頂至底的一條路徑(每一步可沿左斜線向下或右斜線向下),使該路徑經過的數字總和最大。

3. 演算法描述

1)首先該問題有最優子結構和重疊子問題的性質,因此可以用動態規劃來求解。

2)設 a[i][j] 表示數字三角形中的第 i 行第 j 個點;

3)max[i][j]表示 第 i 行 第 j 個數字到低端的最優路徑值,則原問題的最優解就是 max[1][1] 的值;

4)從 a[i][j] 這個點向下走,有 a[i +1][j] 和a[i+1][j+1] 這兩個點可以選擇; 則 max[i][j] 的最優值 = a[i][j] 的值 + max。

5)因為原問題的最優解是 max[1][1],因此填表的順序就是至底向上,先計算最後一層的點,然後倒數二層,……,一直算到第一層。

遞迴公式:

max[i][j]:第 i 行 第 j 個數字到低端的最優路徑值。

max[i][j] = a[i][j] ( i=n)

max[i][j] = max + a[i][j] ( 1 <= i <= j < n)

原問題的最優值是 b[1][1]

4. 演算法時間及空間複雜度分析

時間複雜度:

因為三角形的數字總和為n(n+1)/2,因此填表的時候會有兩重迴圈:行數 i 和列數j 的迴圈,得到的時間複雜度為o(n²)。

空間複雜度:

演算法需要乙個記錄子結構最優解的二維陣列max,這個陣列的規模為n行n列,因此空間複雜度為o(n²)。

5. 程式**

#include 

using

namespace

std;

int a[101][101];

int longestpath(int n)

}return a[1][1];

}int main()

6. 程式執行截圖

7. 心得體會

首先在了解了題目,知道它可以用動態規劃來解決之後,我一開始想到的是用乙個一維陣列來記錄每一層的最優解,自上而下來記錄,但是按照這個思路來想,一直在研究 max[i] 和 max[i+1] 怎麼搭上關係,後來發現無論是從下到上還是從上到下,怎麼樣都沒有辦法記錄,這時候我就知道自己的方向想錯了,可能是理解錯了動態規劃的意思,然後我趕緊複習了一下動態規劃。

後來想到了用乙個二維陣列來記錄每個節點的最優解,我手動填了一次**,發現從下到上還是從上到下寫起都是可以的,但是從下到上寫的話最後可以馬上得到 max[1][1] 就是最優解。但是從上到下寫最後就必須對最底的那一排進行遍歷取得最大值,因此順序從上到下比較省時和方便。

接下來程式就很順利地完成了,最後乙個問題是在記錄節點的最優解時,可以選擇另開乙個二維陣列max來記錄最優解,也可以直接覆蓋記錄原始資料的陣列a,如果新開乙個陣列的話就會演算法的空間複雜度增加,但是如果覆蓋的話,原始資料就會丟失,因此需要根據實際的情景選擇適合的操作方法。

演算法學習 動態規劃

動態規劃是解決多階段決策過程最優化的一種方法。對於離散問題,解析數學無法施展,動態規劃則成為非常有效的工具。兩個弱點 1.得出目標函式方程後,尚無統一的處理方法,必須根據具體問題的性質結合相應的數學技巧來求解 2.維數障礙。動態規劃模型的分類 根據決策過程的時間參量是離散的還是連續的變數 1.離散 ...

演算法學習08 動態規劃

遞迴問題 暴力遞迴轉換成動態規劃 動態規劃本身就是暴力遞迴的優化,是一種用空間換時間的策略 動態規劃 我們不知道怎麼計算n 但我們知道 n 與 n 1 之間存在一定關係n n n 1 得到遞推的狀態轉移公式.當暴力遞迴到頭得到0 1,得到base case,這樣得到了遞迴的方法.public sta...

演算法學習(十)動態規劃!!!

1.先上一波官方解讀提提神 動態規劃 英語 dynamic programming,簡稱dp 是一種在數學 管理科學 電腦科學 經濟學和生物資訊學中使用的,通過把原問題分解為相對簡單的子問題的方式求解複雜問題的方法。動態規劃常常適用於有重疊子問題和最優子結構性質的問題。官方術語太多?不能理解?wha...