動態規劃
阿新 • • 發佈:2020-07-15
動態規劃
動態規劃背後的基本思想非常簡單。大致上,若要解一個給定問題,我們需要解其不同部分(即子問題),再根據子問題的解以得出原問題的解
動態規劃框架
//動態規劃框架
//初始化 base case
dp[0][0][...] = base
//進行狀態轉移
for '狀態1' in '狀態1的所有取值':
for '狀態2' in '狀態2的所有取值':
for ...
dp[狀態1][狀態2][...] = 求最值(選擇1,選擇2...)
通俗的解釋:通過子問題的解逐步累積推匯出原問題的解。
例項1:求最長迴文子串
//dp[j][i] 字串從j->i是否為迴文數 //動態迴歸方程d[i-1][j+i]是否為迴文數 public String longestPalindrome(String s) { int len=s.length(); boolean[][] dp = new boolean[len][len]; int max=-1; String str=""; for (int i = 0; i < len; i++) { for (int j = 0; j <= i; j++) { if (s.charAt(j) == s.charAt(i) && (i - j <= 2 || dp[j+1][i-1])) dp[j][i] = true; if(dp[j][i] && i-j>max) { max=i-j; str=s.substring(j,i+1); } } } return str; }
例項2:輸入一個整型陣列,數組裡有正數也有負數。陣列中的一個或連續多個整陣列成一個子陣列。求所有子陣列的和的最大值。要求時間複雜度為O(n)
/* 字串問題一般都是分解子問題的過程,假設陣列長度只有1個,不用求就只能是這個一元素的大小了,如果是2個元素,3個元素呢 元素個數 最大和 1 [0] 2 max([0]+[1],[1]) 3 max([1]+[2],[2]) 4 max([2]+[3],[3]) ... ... n max([n-1]+[n],[n]) 分析: 1.當[n]>=[n-1]+[n]的時候說明[n-1]對結果產生了副作用,以n-1結尾的錢n項和還不如n項大,那麼n項就作為起點位置了 2.當[n]<[n-1]+[n]的時候說明[n-1]對結果產生了正面作用,繼續判斷下一部分 3.綜合以上分析這明顯就是動態規劃的特徵(核心思想是把原問題分解成子問題進行求解,也就是分治的思想) 4.綜合起來dp[i] 作為以i結尾連續字串最大和,本質就只有三行程式碼 max = dp[0] = nums[0]; dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]) max = Math.max(max, dp[i]); 5. 當[n]>[n-1]+[n]時記錄起始位置下標,當[n-1]+[n]>[n]時記錄結束座標,dp[i]>max時,則記錄最大和 */ //java程式碼 public int maxSubArray(int[] nums) { int len = nums.length; int[] dp = new int[len]; dp[0] = nums[0]; int max = dp[0]; for (int i = 1; i < len; i++) { dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]); max = Math.max(max, dp[i]); } return max; }