動態規劃一般用於全域性問題,在構造遞迴的時候,一般採用自頂向下分解的方法,先把全域性問題分解成更小的子問題求解。下面舉兩個例子
例子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 每組測試資料都只有一行,是乙個字串...