簡單來說,解動態規劃的時候需要開乙個陣列,陣列的每個元素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 從第一行的數開始,每次可以往下或往右下走一格,直到走到最下行,把沿途...