動態規劃入門專題(超詳細!!!)

2021-10-09 10:17:31 字數 3274 閱讀 5074

簡單來說,解動態規劃的時候需要開乙個陣列,陣列的每個元素f[i]或f[i][j]代表什麼(類似於解數學題中,x、y、z 代表什麼)

確定狀態需要兩個意識

最後一步(最優策略中的最後乙個決策)

子問題(問題相同,但規模變小)

其中初始條件往往是用轉移方程無法求得出結果,需要人為定義。

大多數情況:從小到大(一維)從上到下從左到右(二維)

你有三種硬幣,分別面值2元,5元和7元,每種硬幣都有足夠多

買一本書需要27元

如何用最少的硬幣組合正好付清,不需要對方找錢

分析1.確定狀態

此時最後一枚硬幣為最後一步(即去掉這一步後,前面的k-1枚硬幣依然為最優策略)

所以此時問題可以從原來的「最少用多少枚硬幣拼出27」轉化為乙個子問題,而且規模更小「最少用多少枚硬幣可以拼出27-ak」。

為簡化定義,設狀態f(x) = 最少用多少枚硬幣拼出x

由於ak的取值情況只可能是2,5或者7

故如果ak為2,則f(27) = f(27-2) + 1(加上最後這一枚硬幣2)

如果ak為2,則f(27) = f(27-5) + 1(加上最後這一枚硬幣5)

如果ak為2,則f(27) = f(27-7) + 1(加上最後這一枚硬幣7)

需要求最少的硬幣數,所以:

f(27) = min

2.轉移方程

轉移方程形式:f[x] = min

3.初始條件和邊界情況

若不能拼出y,則定義f[y] = +∞

eg:f[1] = min = +∞ (表示拼不出來1)

初始條件:f[0] = 0

4.計算順序

計算f[1],f[2],f[3],…,f[27]

當我們計算到f[x]時,f[x-2],f[x-5],f[x-7]都已經得到結果了

**部分

class

solution}}

if(result[amount]

== max_value)

return-1

;else

return result[amount];}

};

給定m行n列的網格,有乙個機械人從左上角(0,0)出發,每一步可以向下或者向右走一步

問有多少種不同的方式走到右下角

分析1.確定狀態

最後一步:無論機械人用何種方式到達右下角,總有最後挪動一步:向右或向下

右下角座標設為(m-1,n-1)

則前一步機械人一定在(m-2,n-1)或(m-1,n-2)

子問題:

原題「求有多少種方式從左上角走到(m-1,n-1)」

子問題「求有多少種方式從左上角走到(m-2,n-1)和(m-1,n-2)」

狀態:設f[i][j]為機械人有多少種方式從左上角走到(i,j)(有多少變數就開幾維陣列

2.轉移方程

對於任意乙個格仔(i,j)

f[i][j]:有多少種方式從左上角走到(i,j)

f[i][j] = f[i-1][j] + f[i][j-1]

3.初始條件和邊界情況

初始條件:f[0][0] = 1 //機械人只有一種方式到左上角

邊界情況:i=0或j=0,則前一步只能由乙個方向過來—>f[i][j] = 1

4.計算順序

f[0][0] = 1

計算第0行:f[0][0],f[0][1],f[0][2],…,f[0][n-1]

計算第1行:f[1][0],f[1][1],f[1][2],…,f[1][n-1]

…計算第m-1行:f[m-1][0],f[m-1][1],f[m-1][2],…,f[m-1][n-1]

答案:f[m-1][n-1]

時間複雜度度(計算步數):o(mn)

空間複雜度(陣列大小):o(mn)

**部分

class

solution

}return f[m-1]

[n-1];}};

有n塊石頭分別在x軸的0,1,…,n-1位置

乙隻青蛙在石頭0,想跳到石頭n-1

如果青蛙在第i塊石頭上,它最多可以向右跳距離ai

問青蛙能否跳到石頭n-1

例子:輸入:a = [2, 3, 1, 1, 4]

輸出:true

輸入:a = [3, 2, 1, 0, 4]

輸出:false

1.確定狀態

最後一步:如果青蛙能跳到最後一塊石頭n-1,我們考慮它跳的最後一步

這一步是從石頭i跳過來,i < n-1

這需要兩個條件同時滿足:

a.青蛙可以跳到石頭i

b.最後一步不超過最大跳躍距離:n-1-i <= ai

原問題「求青蛙能不能跳到石頭n-1」

子問題「求青蛙能不能跳到石頭i(i < n-1)」

狀態:設f[j]表示青蛙能不能跳到石頭j

2.轉移方程

設f[j]表示青蛙能不能跳到石頭j

f[j] = or(0<= i <=j-1)(f[i] and i + a[i] >= j)

其中(0<= i <=j-1)表示列舉上乙個跳到石頭i

f[i]表示青蛙能不能跳到石頭i

i + a[i] >= j 表示最後一步不能超過ai

or表示只要有乙個i滿足即返回true,否則返回false

3.初始條件和邊界情況

初始條件:f[0] = true,因為青蛙一開始就在石頭0

邊界情況:不會越界

4.計算順序

計算f[0], f[1], f[2], … , f[n-1]

答案是f[n-1]

時間複雜度:o(n^2) 空間複雜度(陣列大學):o(n)

**部分

class

solution}}

return f[n-1]

;}};

研究最優策略的最後一步

化為子問題

根據子問題定義直接得到

細心、考慮周全

利用之前的結果

動態規劃入門

1 用 dp 做的題大多數返回值是int boolean,求max min,不能打亂原來輸入順序。2 動態規劃有兩個重要定義,乙個叫 optimal substructure 另乙個叫 overlap subproblem 各種排序 tree 類問題中,都會用到 divide conquer 的思想...

動態規劃入門

大家可以看看這篇文章dp,哪個更容易理解就看哪個!一 動態規劃的定義 動態規劃程式設計是一種針對於解決最優化問題的一種途徑 一種方法,而不是一種特殊演算法,也就是說它沒有固定的模板。在動態規劃中,每走一步都要看看能不能最優,而且動態規劃最擅長的就是多階段問題!二 動態規劃的基本概和基本模型構成 1....

動態規劃入門

學動態規劃自然要從數字三角形開始起步,那麼我們就先從數字三角形開始。數字三角形題目 有乙個由非負整數組成的三角形,第一行只有乙個數,除了最下行之外的每個數的左下方和右下方各有乙個數,如下圖所示 3 24 10 1 4 3 2 20 從第一行的數開始,每次可以往下或往右下走一格,直到走到最下行,把沿途...