動態規劃是最重要、最經典的演算法之一,學好動態規劃對我們十分重要,掌握動態規劃對解決某些問題會起到事半功倍的效果。
特點:
①可以把原始問題劃分為一系列子問題
②求解每個子問題僅一次,並將其結果儲存到乙個表中,以後用到時直接訪問,不重複計算,節省時間。
③自底向上地計算
適用範圍:
原問題可以分為多個相關子問題,子問題的解會被重複使用。
動態規劃和遞迴或者分治沒有根本上的區別(關鍵看有無最優子結構)。
**共性:**找到重複子問題
**差異性:**最優子結構、中途可以淘汰次優解。
1.計數
-有多少種方式走到右下角
-有多少種方法選出k個數的和為sum
2.求最大最小值
-從左上角到右下角路徑的最大數字和
-最長上公升子串行長度
3.求存在性
-取石子遊戲,先手是否必勝
-能不能選出k個數使得和是sum
下面我會用一些力扣上的動態規劃經典例題來解釋動態規劃的用法。請大家將題目和上面的問題特點對號入座。
題目1:零錢兌換
題目鏈結
給定不同面額的硬幣 coins 和乙個總金額 amount。編寫乙個函式來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 -1。
題解:
這道題可以從前往後推,如果目標錢數是0,湊成總金額所需的最少的硬幣個數是多少;
目標是1,會怎樣呢,…直到目標錢數為amount,需要的最少硬幣又是多少呢?
首先要看最後一步,最後一步肯定是dp[i]置為dp[i-coins[j]]+1中最小的那個。所以轉換為正推,
如果無法湊夠則先把硬幣數dp[i]置為最大int_max;否則,則把dp[i]置為最小的dp[i-coins[j]]+1.
然後最後判斷一下,如果dp[amount]是否為int_max,如果是,說明無法湊齊,返回-1,如果不是,說明dp[amount]就是最少硬幣數。
重要的就是轉移方程:dp[i]=min(dp[i],dp[i-coins[j]]+1);
**:
class
solution}}
return dp[amount]
==int_max?-1
:dp[amount];}
};
題目2:不同路徑題目鏈結
乙個機械人位於乙個 m x n 網格的左上角 (起始點在下圖中標記為「start」 )。
機械人每次只能向下或者向右移動一步。機械人試圖達到網格的右下角(在下圖中標記為「finish」)。
問總共有多少條不同的路徑?
題解:
我們首先看最後一步,要想到達(m,n)首先要到達(m-1,n)或者(m,n-1)。設到達(m-1,n)路徑有x種,到達(m,n-1)路徑有y種,則到達(m,n)的路徑有x+y種。
然後再從頭看起,到達(1,2)路徑只有1種,到達(2,1)路徑只有1種,到達(i,j)的路徑數是到達(i-1,j)和(i,j-1)的路徑和。
重點:轉移方程:dp[i][j]=dp[i-1][j]+dp[i][j-1];
**:
class
solution
else}}
return dp[m-1]
[n-1];}};
題目3:跳躍遊戲題目鏈結
給定乙個非負整數陣列,你最初位於陣列的第乙個位置。陣列中的每個元素代表你在該位置可以跳躍的最大長度。判斷你是否能夠到達最後乙個位置。
題解:
我們首先從後面看,要想到達下標為n-1的地方,有兩個條件:①能到達下標為 i 的地方;②從 i 能調到 j 。所以我們就得到了轉移方程:if(dp[j]&&j+nums[j]>=i) dp[j]=true;
然後我們再從頭遍歷,判斷每個下標為 i 的地方演算法能調到,最後返回dp[n-1]即可。
**:
class
solution}}
return dp[nums.
size()
-1];}};
題目4:揹包問題因為揹包問題比較重要,所以我單獨把揹包問題拿出來單獨寫一篇部落格。
傳送門
題目5:最大子列和
題目鏈結
給定乙個整數陣列 nums ,找到乙個具有最大和的連續子陣列(子陣列最少包含乙個元素),返回其最大和。
題解:
如果陣列中只有1個數,那麼最大子列和就是該數值。如果大於1個,依次遍歷陣列,如果沒考慮當前數的時候,最大子列和小於0,那麼考慮到這個數時最大子列和就是該數值;如果沒考慮當前數的時候,最大子列和小於0,那麼考慮到這個數時最大子列和就是該數值加上之前的最大子列和。然後從這些子列和中選出最大的即可。(可以直接看**,**通俗易懂.)
**:
class
solution
return maxsum;}}
;
動態規劃經典例題(二)
最長公共子列 輸入 abcfbc abfcab programming contest abcd mnp 輸出 420 解題思路 和最求最長上公升子列一樣,先設定乙個陣列儲存比較過的狀態maxlen,一步步的從子問題推到最終問題。設乙個二維陣列maxlen 最長公共子串ad cba1 111b 11...
動態規劃例題
題目描述 有一條很長的數軸,一開始你在0的位置。接下來你要走n步,第i步你可以往右走ai或者bi。問n步之後,0到m的每個位置,能不能走到?輸入格式 第一行,兩個整數n,m。接下來n行,每行兩個整數ai,bi。輸出格式 一行,一共m 1個數,每個數都是0或1表示能否走到,數字之間不用空格隔開。樣例輸...
《動態規劃》 ACM 動態規劃例題詳解
描述 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 圖1 圖1給出了乙個數字三角形。從三角形的頂部到底部有很多條不同的路徑。對於每條路徑,把路徑上面的數加起來可以得到乙個和,你的任務就是找到最大的和。注意 路徑上的每一步只能從乙個數走到下一層上和它最近的左邊的那個數或者右邊的那個數。輸...