動態規劃(四)-劃分型動態規劃
阿新 • • 發佈:2020-12-31
一.例1.LintCode 513 Perfect Squares
- 題意:給定一個正整數n,問最少可以將n分成幾個完全平方數(1,4,9…)之和
- 例子:輸入:n=13,輸出:2(13=4+9)
1.確定狀態
- 最後一步:關注最優策略中最後一個完全平方數j²
- 最優策略中n-j²也一定被劃分成最少的完全平方數之和
- 需要知道n-j²最少被分成幾個完全平方數之和,原來求n最少被分成幾個完全平方數之和
- 子問題
- 狀態:設f[i]表示i最少被分成多少個完全平方數之和
- 劃分一般都是設定成二維陣列,比如f[i][j],前i個元素被劃分成j段,但是這裡為什麼不要j?最少劃分為幾個平方數之和,沒說劃分成多少個(一個定值),限定劃分次數的時候,就需要記錄,f[i][j]表示f[i]能不能被分成j個,不需要分成一個指定值,所以不需要記錄
2.轉移方程
- 設f[i]表示i最少被分成幾個完全平方數之和
3.初始條件和邊界情況
- 設f[i]表示i最少被分成幾個完全平方數之和
- f[i]=min(1<=j乘j<=i){f[i-j²]+1}
- 初始條件:0被分成0個完全平方數之和
- f[0]=0
4.計算順序
- 初始化f[0]
- 計算f[1]…f[N]
- 答案是f[N]
- 時間複雜度n*根號n(i從1到n,j從1到根號i)
5.程式碼
public class Solution {
public int numSquares(int n) {
int [] dp = new int[n+1];
dp[0]= 0;
for(int i=1;i<=n;i++){
dp[i]=Integer.MAX_VALUE;
for(int j=1;j*j<=i;j++){
dp[i]=Math.min(dp[i-j*j]+1,dp[i]);
}
}
return dp[n]
}
}
例2.LintCode 108 Palindrome Partitioning II
- 題意:給定一個字串S[0…N-1],要求將這個字串劃分成若干段,每一段都是一個迴文串,求最少劃分幾次
- 例子:輸入:“aab”,輸出:1(劃分1次 “aa”,“b”)
第一步:確定狀態
- 最後一步:關注最優策略中最後一段迴文串,設S[j…N-1]
- 需要知道S前j個字元[0…j-1]最少可以劃分成幾個迴文串