題目連接:https://leetcode.com/problems/integer-break/description/html
題目大意:給定一個天然數,將其分解,對其分解的數做乘積,找出最大的乘積結果。例子以下:ide
法一(借鑑):dp,一維dp,dp[i]表示i的最大分解結果的乘積,而dp[5]能夠dp[4],dp[3],dp[2],dp[1]爲基礎,dp[4]能夠dp[3],dp[2],dp[1]爲基礎,代碼以下(耗時1ms):this
1 //dp[i]表示給定i分解後能獲得的最大乘積值 2 public int integerBreak(int n) { 3 int dp[] = new int[n + 1]; 4 dp[1] = 1; 5 dp[2] = 1; 6 for(int i = 3; i <= n; i++) { 7 for(int j = 1; j <= i / 2; j++) { 8 //max裏面要加上dp[i],由於裏層for循環會不斷更新dp[i],不然dp[i]獲得就是最後一次的計算結果,而取不到最大值 9 //後面Math.max(j, dp[j]) * Math.max(i - j, dp[i - j]),由於j+(i-j)=i,因此計算j和i-j的乘積,是正常的,只不過這裏能夠用到先前已經算過的dp[j]和dp[i-j],由於dp[j]的結果就是j的最大分解結果,那麼也能夠是i的分解結果 10 dp[i] = Math.max(dp[i], Math.max(j, dp[j]) * Math.max(i - j, dp[i - j])); 11 } 12 } 13 return dp[n]; 14 }
法二(借鑑):數學方法,數學原理:https://leetcode.com/problems/integer-break/discuss/80721/Why-factor-2-or-3-The-math-behind-this-problem.,由數學知,一個整數分解,當分解成相同的數時,乘積最大,而因爲給定的天然數不必定都能分解成相同的數,因此又由數學知,求導辦法見http://www.javashuo.com/article/p-mohovvjr-ch.html,當分解獲得的數越靠近e,獲得的乘積值越大,那麼也就是能取3則取3,不能則取2。而又如6=2+2+2=3+3,又2*2*2<3*3,因此當能分解成3個2時,應該換算成2個3,因此下面與3求餘,而後分狀況分解。代碼以下(耗時0):spa
1 public int integerBreak(int n) { 2 if(n == 2) { 3 return 1; 4 } 5 else if(n == 3) { 6 return 2; 7 } 8 else if(n == 1) { 9 return 1; 10 } 11 else if(n % 3 == 0) { 12 return (int)Math.pow(3, n / 3); 13 } 14 else if(n % 3 == 1) { 15 return 2 * 2 * (int)Math.pow(3, (n - 4) / 3); 16 } 17 else { 18 return 2 * (int)Math.pow(3, (n - 2) / 3); 19 } 20 }