1. 程式人生 > 其它 >動態規劃(四)-劃分型動態規劃

動態規劃(四)-劃分型動態規劃

技術標籤:演算法ACM-dp(動態規劃)動態規劃演算法

一.例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]最少可以劃分成幾個迴文串