JS 動態規劃入門

2022-08-26 13:15:13 字數 3162 閱讀 5615

計數

求最大值最小值

求存在性

解題步驟

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 從第一行的數開始,每次可以往下或往右下走一格,直到走到最下行,把沿途...