計數
求最大值最小值
求存在性
解題步驟
1. 確定步驟
狀態在動態規劃中的作用屬於定海神針。
簡單來說, 解動態規劃的時候需要開乙個陣列, 陣列的每個元素f【i】或者f【i】【j】代表什麼
確定狀態需要兩個意識:
2. 轉移方程
f【x】 = f【x-1】
3. 初始化條件和邊界情況
初始條件, 用轉移方程算不出來, 需要手動定義
邊界情況, 陣列不要越界,向上越界,向下越界
4. 計算順序
當我們計算到f【x】時, 右邊的都已經得到結果了
題目一最後一步
雖然我們不知道最優策略是什麼, 但是最優策略肯定是k枚硬幣a1, a2... ak面值加起來是27
所以一定有一枚最後的硬幣:ak
除掉這枚硬幣, 前面的面值加起來是27 - ak
關鍵點我們不關心前面的k-1枚硬幣是怎麼拼出27-ak的(可能有一種拼法, 可能有100中拼法), 而且我們現在甚至還不知道ak和k, 但是我們確定前面的硬幣拼出了27-ak
因為是最優策略, 所以拼出27-ak的硬幣數一定要最少, 否則這就不是最優策略了
子問題所以我們就要求: 最少用多少枚硬幣可以拼出27-ak
原問題是最少用多少問題拼出27
我們將原問題轉化成了乙個子問題, 而且規模更小: 27-ak
為了簡化定義, 我們設狀態f(x) = 最少用多少枚硬幣拼出x
等等,我們還不知道最後那一枚硬幣ak是多少
最後那枚硬幣ak只可能是2,5或者7
如果ak是2,f(27)應該是f(27-2)+1(加上最後這一枚硬幣2)
如果ak是5,f(27)應該是f(27-5)+1(加上最後這一枚硬幣5)
如果ak是7,f(27)應該是f(27-7)+1(加上最後這一枚硬幣7)
除此之外, 沒有其他的可能了
需要求最少的硬幣數,所以:
f(27) = min(f(27-2)+1, f(27-5)+1, f(27-7)+1)
轉移方程
設狀態f【x】=最少用多少枚硬幣拼出x
對於任意x
f【x】= min
初始化條件和邊界情況
f【x】= min
兩個問題
如果不能拼出y,就定義f【y】=正無窮, 例如f【-1】=f【-2】 = 。。。 = 正無窮
所以f = min【f【-1】+1,f【-4】+1, f【-6】+1】 = 正無窮, 表示拼不出來1
初始條件: f= 0
計算順序
從小到大,乙個for迴圈搞定
/**
* * @param a
* @param m
*/function coinchange(a, m)}}
if(f[m] == number.max_value)
return f[m]
}
小結
求最值規劃組成的部分:
確定狀態
轉移方程
初始條件和邊界情況
計算順序
動態規劃:
消除冗餘, 加速計算
題目二給定m行n列的網格, 有乙個機械人從左上角(0,0)出發, 每一步可以向下或者向右走一步。
問有多少種不同的方式走到右下角。
確定狀態
最後一步: 無論機械人用何種方式到達右下角, 總有最後挪動的一步: 向右或者向下
右下角座標設為(m-1, n-1)
那麼前一步機械人一定是在(m-2,n-1)或者(m-1, n-2)
子問題:
那麼, 如果機械人有x種方式從左上角走到(m-2,n-1),有y種方式從左上角走到(m-1,n-2),則機械人有x+y種方式走到(m-1,n-1)
問題轉化為:
機械人有多少種方式從左上角走到(m-2,n-1)和(m-1,n-2)
原題要求有多少方式從左上角走到(m-1,n-1)
狀態:設f【i】【j】為機械人有多少種方式從左上角走到(i,j)
對於任意乙個格仔(i,j)
f【i】【j】=f【i-1】【j】 + f【i】f【j-1】
機械人有多少種方式走到(i,j) = 機械人有多少種方式走到(i-1,j) + 機械人有多少種方式走到(i,j-1)
初始條件和邊界情況
初始條件:f=1,因為機械人只有一種方式到左上角
邊界情況:i = 0 或 j = 0, 則前一步只能有乙個方向過來->f【i】【j】= 1
計算順序
f = 1
計算第0行: f, f
答案是f【m-1】【n-1】
**
function uniquepaths(m, n) else
}} return f[m - 1][n - 1];
}
青蛙跳石頭
有n塊石頭分別在x軸的0, 1, 。。。n-1位置
乙隻青蛙在石頭0, 想跳到石頭n-1
如果青蛙在第i塊石頭上,他最多可以向右跳距離ai
問青蛙能否跳到石頭n-1
例子確定狀態
這需要兩個條件同時滿足
子問題狀態: 設f【j】表示青蛙能不能跳到石頭j
f【j】= or(f【i】and i + a【i】>= j)
0 <= i < j: 列舉上乙個跳到的石頭i
f【i】: 青蛙能不能跳到石頭i
i + a【i】>= j:最後一步的距離不能超過ai
初始條件和邊界情況
初始條件: f = true, 因為青蛙一開始就在石頭0
沒有邊界情況: 因為列舉不存在越界情況
計算順序
從左到右
答案是f【n-1】
時間復炸度:o(n^2),空間複雜度陣列大小:o(n)
**
function conjump(a)
}} return f[n - 1];
}var r1 = conjump([2, 3, 1, 1, 4]);
var r2 = conjump([3, 2, 1, 0, 4]);
console.log(r1);
console.log(r2);
四個組成部分
確定狀態
轉移方程
初始條件和邊界情況
計算順序
動態規劃入門
1 用 dp 做的題大多數返回值是int boolean,求max min,不能打亂原來輸入順序。2 動態規劃有兩個重要定義,乙個叫 optimal substructure 另乙個叫 overlap subproblem 各種排序 tree 類問題中,都會用到 divide conquer 的思想...
動態規劃入門
大家可以看看這篇文章dp,哪個更容易理解就看哪個!一 動態規劃的定義 動態規劃程式設計是一種針對於解決最優化問題的一種途徑 一種方法,而不是一種特殊演算法,也就是說它沒有固定的模板。在動態規劃中,每走一步都要看看能不能最優,而且動態規劃最擅長的就是多階段問題!二 動態規劃的基本概和基本模型構成 1....
動態規劃入門
學動態規劃自然要從數字三角形開始起步,那麼我們就先從數字三角形開始。數字三角形題目 有乙個由非負整數組成的三角形,第一行只有乙個數,除了最下行之外的每個數的左下方和右下方各有乙個數,如下圖所示 3 24 10 1 4 3 2 20 從第一行的數開始,每次可以往下或往右下走一格,直到走到最下行,把沿途...