資料結構 十二 動態規劃

2021-08-15 14:14:29 字數 2414 閱讀 1769

動態規劃一般用於全域性問題,在構造遞迴的時候,一般採用自頂向下分解的方法,先把全域性問題分解成更小的子問題求解。下面舉兩個例子

例子1

有一座高度是10

階的樓梯,從下往上走,每跨一步可以是一級或兩級台階。要求用程式求出一共一共有多少種走法。

問題分析建模:首先總共有10

步,假設只剩最後一步就到達第

10階,這個時候會有兩種情況:第一種是從第九階到第十階,第二種是從第八階到第十階

,然後兩種情況裡面如何從第乙個階梯走到第九階,從第乙個階梯走到第八階。也就是我們可以構造出最後一步的函式:

f(10)=f(9)+f(8)

這個時候我們就可以構造出遞迴函式:

f(n)=f(n-1)+f(n-2)

寫成通用一點的公式,也就是用for

迴圈遍歷最後一次的情況:

f(n)=sum(f(n-j)) 且

j=1,2

因此我們只要知道初始值f(1)

、f(2)

就可以求解

f(10)

。這種我們稱之為一維動態規劃。

例子2:給定乙個

m*n矩陣

a,從左上角開始每次只能向右走或者向下走,最後達到右下角的位置,路徑中所有數字累加起來就是路徑和,返回所有路徑的最小路徑和,如果給定的矩陣如下,那麼路徑

1,3,1,0,6,1,0

就是最小路徑和,返回12。

1 3 5 9

8 1 3 4

5 0 6 1

8 8 4 0

問題分析建模:對於這個題目,假設m是m

行n列的矩陣,那麼我們用

dist[m][n]

來抽象這個問題,

dist[i][j]

表示的是從原點到

i,j位置的最短路徑和。我們要求解的是

dist[m][n]

的最大值

,然而其實最後一步

dist[m][n]

又可以分解成兩種情況,從

dist[m-1][n]

往下走;從

dist[m][n-1]

往右走,取這兩種情況的最小值,那麼我們就可以列出方程:

dist[m][n]=min(dist[m-1][n]+a[m][n],dist[m][n-1]+a[m][n])

抽取出a[m][n]

,該方程可以進一步寫成:

dist[m][n]=a[m][n]+min(dist[m-1][n],dist[m][n-1])

因此接著我們只需要根據初始條件,就可以求解,初始條件dist[0][0]=1

。這個例子又稱之為二維動態規劃。

(1)自頂向下遞迴

其主要原理是加入備忘錄,用於記錄之前已經記錄過的函式值,比如在寫例子1遞迴函式:

f(n)=f(n-1)+f(n-2)

**的時候,用乙個陣列記錄一下f(i),

然後在寫遞迴函式的時候,遇到

f(i)

的值如果已經被計算過一次了,那麼就不用繼續計算了;如果還沒有被記錄,那麼就儲存一下

f(i)

。在寫例子2

遞迴函式的時候,用二維的陣列

f[m][n]

記錄一下已經計算過的函式值

(2)自底向上迭代

從0開始往上迭代,比如對於例子

1,先求:

f[2]=f[1]+f[0]

f[3]=f[2]+f[1]

f[4]=f[3]+f[3]

直到迭代到f[10]

為止。

#include ;

#include ;

#include using namespace std;

int a[4][4] = ;

int f[4][4]=;//備忘錄

int count=0;//統一一下採用備忘錄的時候,減少的計算次數

int function_top2bottom(int m,int n)

else if (m-1>=0&&n==0)

min_dist=function_top2bottom(m-1,n);

else if (m==0&&n-1>=0)

else

f[m][n]=min_dist+a[m][n];

return f[m][n];

}int function_bottom2top(int m,int n)

else

f[m][n]=min_dist+a[m][n];}}

return f[m][n];

}void dynamic_programming()

(十二)動態SQL之if trim

q mybatis動態sql有什麼用?執行原理?有哪些動態sql?mybatis動態sql可以在xml對映檔案內,以標籤的形式編寫動態sql,執行原理是根據表示式的值完成邏輯判斷並動態拼接sql的功能 mybatis提供了9種動態sql標籤 trim where set foreach if cho...

資料結構研究之十二 高等動態規劃法

1.硬幣問題 a.題目 給定面值不同的m種硬幣,求支付n元時的最少硬幣數,各硬幣可以重複使用 b.核心思路 關鍵在於使用t i j j 表示用第i種硬幣支付j元的情況,這表示是否使用第i種硬幣 c.created by 葉子 on 2018 2 8.硬幣問題 include iostream usi...

括號匹配(二)(動態規劃)

時間限制 1000 ms 記憶體限制 65535 kb 難度 6 描述 給你乙個字串,裡面只包含 四種符號,請問你需要至少新增多少個括號才能使這些括號匹配起來。如 是匹配的 是匹配的 是不匹配的 是不匹配的 輸入 第一行輸入乙個正整數n,表示測試資料組數 n 10 每組測試資料都只有一行,是乙個字串...