動態規劃學習記錄

2021-10-09 10:15:27 字數 4089 閱讀 4736

動態規劃一般用陣列記錄下每一步的最優值,返回最後一步的值就是最優結果,相對於遞迴解法消除了重複計算的部分,提高的效率。

計數:有多少種方式從a到b、多少種方式取得某值、、、

求最優解:最大值最小值、路徑上最大資料和。

存在性問題:能不能選出和為k的數、、、

選定演算法前一定要判斷是否為動態規劃解題、有時候問題相似但不能用動態規劃求解。

以leetcode 322 零錢兌換 為例:

給定不同面額的硬幣 coins 和乙個總金額 amount。

編寫乙個函式來計算可以湊成總金額所需的最少的硬幣個數。

如果沒有任何一種硬幣組合能組成總金額,返回 -1。

示例 1:

輸入: coins = [1, 2, 5], amount = 11

輸出: 3

解釋: 11 = 5 + 5 + 1

示例 2:

輸入: coins = [2], amount = 3

輸出: -1

說明:你可以認為每種硬幣的數量是無限的。

首先要確定狀態就是解決問題的最後一步和確定子問題

由之前的結果寫出轉移方程

對於示例1:f(x)=min

對於示例1:

動態規劃一般都是以自底向上進行迴圈迭代計算,

而帶備忘錄的遞迴則是自頂向下進行計算。

在例題中:轉移方程計算左邊時,右邊的內容都需要已經有結果了

計算f(11)時需要f(10)、f(9)、f(6)的具體值,那麼從小到大計算(根據題目以及選定解題方式選定計算順序)。

最後是編碼,與理論不一樣,程式編碼中很多要注意的地方,如

public

intcoinchange

(int

coins,

int amount)}}

if(f[amount]

== integer.max_value)

return f[amount]

;}

例題

力扣 62.題不同路徑

乙個機械人位於乙個 m x n 網格的左上角 (起始點在下圖中標記為「start」 )。

機械人每次只能向下或者向右移動一步。機械人試圖達到網格的右下角(在下圖中標記為「finish」)。

問總共有多少條不同的路徑?

例如,上圖是乙個7 x 3 的網格。有多少可能的路徑?

示例 1:

輸入: m = 3, n = 2

輸出: 3

解釋:從左上角開始,總共有 3 條路徑可以到達右下角。

1. 向右 -> 向右 -> 向下

2. 向右 -> 向下 -> 向右

3. 向下 -> 向右 -> 向右

示例 2:

輸入: m = 7, n = 3

輸出: 28

1 <= m, n <= 100

題目資料保證答案小於等於 2 * 10 ^ 9

解題步驟:確定最後一步:到達右下角的路徑數。

確定子問題:到達當前格仔路徑數量=到達上面各自數量+到達左邊格仔數量。

做出轉移方程:f(x)(y)=f(x-1)(y)+f(x)(y-1)

確定初始條件和邊界:第一行和第一列每格到達路徑數都為1。

確定計算順序:計算當前格需要知道上面格仔與左邊格仔的路徑數量->從前往後。

編碼:

例題 63.不同路徑ⅱ

乙個機械人位於乙個 m x n 網格的左上角 (起始點在下圖中標記為「start」 )。

機械人每次只能向下或者向右移動一步。機械人試圖達到網格的右下角(在下圖中標記為「finish」)。

現在考慮網格中有障礙物。那麼從左上角到右下角將會有多少條不同的路徑?

網格中的障礙物和空位置分別用 1 和 0 來表示。

說明:m 和 n 的值均不超過 100。

示例 1:

輸入:[

[0,0,0],

[0,1,0],

[0,0,0]

]輸出: 2

解釋:3x3 網格的正中間有乙個障礙物。

從左上角到右下角一共有 2 條不同的路徑:

1. 向右 -> 向右 -> 向下 -> 向下

2. 向下 -> 向下 -> 向右 -> 向右

解題步驟:確定最後一步:到達右下角的路徑數。

確定子問題:到達當前格仔路徑數量=到達上面各自數量+到達左邊格仔數量(前提為計算的格仔都不包含障礙物)。

做出轉移方程:f(x)(y)(不是障礙物)=f(x-1)(y)(不是障礙物)+f(x)(y-1)(不是障礙物)

確定初始條件和邊界:有障礙物就為0;第一格不是障礙物就為1。

確定計算順序:計算當前格需要知道上面格仔與左邊格仔的路徑數量->從前往後。

編碼:

例題 70.爬樓梯

假設你正在爬樓梯。需要 n 階你才能到達樓頂。

每次你可以爬 1 或 2 個台階。你有多少種不同的方法可以爬到樓頂呢?

注意:給定 n 是乙個正整數。

示例 1:

輸入: 2

輸出: 2

解釋: 有兩種方法可以爬到樓頂。

1. 1 階 + 1 階

2. 2 階

示例 2:

輸入: 3

輸出: 3

解釋: 有三種方法可以爬到樓頂。

1. 1 階 + 1 階 + 1 階

2. 1 階 + 2 階

3. 2 階 + 1 階

解題步驟:確定最後一步:到達樓頂

確定子問題:到達當前階層方法數量=前一層數量踏一步+上上層數量踏兩步。

做出轉移方程:f(x)=f(x-1)+f(x-2)

確定初始條件和邊界:第一層為1,第二層為2。

編碼:

不用陣列的話:

經典動態規劃學習記錄

動態規劃本質是一種用空間換時間的優化方法,通常來優化可以暴力搜尋求解的問題,也就是去冗餘,把之前計算過的存下來,而且是規定了遞迴的計算順序,從簡單基本的出發,依次計算 這也是他優於記憶搜尋的地方 方法大概如下 1.首先能明白暴力遞迴怎麼實現 重要 2.找到函式中可以代表遞迴過程的引數 3.引數為ke...

動態規劃學習

首先是01揹包問題,可以把它看做是乙個 行和列分別是體積從1,2,v,每個物品的花費c1,c2,cn,每個空格裡的數代表放入第i個物品在體積為j的揹包裡的最大價值。dp j 表示體積為j的揹包,放入物品後,可以得到的最大值。狀態轉移方程為if j c i dp j max dp j dp j c i...

動態規劃學習

把位置 i,j 看成乙個狀態,然後定義狀態 i,j 的指標函式d i,j 從位置 i,j 出發時能得到的最大和。int i,j 邊界值處理 for j 1 j n j result n j data n j 由下向上動態規劃,儲存葉子節點到當前節點的最大值 for i n 1 i 1 i for j...