343.整數拆分
阿新 • • 發佈:2021-08-29
目錄
,也就是把7繼續拆,這裡就大數拆小數,需要用到之前的狀態,那麼可以試試動態規劃。
343.整數拆分
題目
給定一個正整數 n,將其拆分為至少兩個正整數的和,並使這些整數的乘積最大化。 返回你可以獲得的最大乘積。
示例 1:
輸入: 2
輸出: 1
解釋: 2 = 1 + 1, 1 × 1 = 1。
示例 2:
輸入: 10
輸出: 36
解釋: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
說明: 你可以假設 n 不小於 2 且不大於 58。
題解
m*(n-m)
就保證了和為i,並且計算乘積進行比較。
m從1取到n-1,取到i的話有個乘數就為0,結果就是0,是最小的乘積。
但是拆分的個數是不確定的。假設n=10,3*7=21
,這裡就把7又看成一個新的m*(n-m)
所以拆法有這兩種那麼我們選擇哪種?題目是求最大乘積,誰大選誰
1.確定dp陣列以及下標的含義
dp[i] 表示i的最大乘積
2.確定遞推公式
dp[i] = Math.max(j*(i-j),j*dp[i-j])
需要注意的是j是從1取到i-1,那麼j應該屬於內迴圈,j在變化的時候還應該比較之前dp[i]和現在新的j產生的最大乘積之間的大小
dp[i] =Math.max(Math.max(j*(i-j),j*dp[i-j]))
3.dp陣列如何初始化
dp[0] = 0
dp[1] = 0 dp[0]和dp[1]其實沒有意義的
dp[2] = 1
n從2開始
4.確定遍歷順序
要利用之前的資料,應該從左到右遍歷
程式碼
class Solution { public int integerBreak(int n) { int [] dp = new int [n+1]; dp[2] = 1; for(int i=3;i<n+1;i++){ for(int j=1;j<=((i+1)/2);j++){ //由於對稱性 2*3 和3*2 是一樣的 dp[i] = Math.max(dp[i],Math.max(j*(i-j),j*dp[i-j])); } } return dp[n]; } }