动态规划:整数拆分

343. 整数拆分

给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。

输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。

思路

动规五部曲

  1. 确定dp数组(dp table)以及下标的含义
    dp[i]:分拆数字i,可以得到的最大乘积为dp[i]。

  2. 确定递推公式
    dp[i]最大乘积:可以从1遍历j,然后有两种渠道得到dp[i]。

    • 一个是j * (i - j) 直接相乘。
    • 一个是j * dp[i - j],相当于是拆分(i - j)。
      j是从1开始遍历,在遍历j的过程中其拆分的情况都计算过了。
      递推公式:dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));
  3. dp的初始化
    严格从dp[i]的定义来说,dp[0] dp[1] 就不应该初始化,也就是没有意义的数值。
    所以只初始化dp[2] = 1(拆分数字2,得到的最大乘积是1)。

  4. 确定遍历顺序
    dp[i] 是依靠 dp[i - j]的状态,所以遍历i一定是从前向后遍历,先有dp[i - j]再有dp[i]。
    枚举j的时候,是从1开始的。i是从3开始,这样dp[i - j]就是dp[2],正好可以通过初始化的数值求出来。

  5. 举例推导dp数组
    举例当n为10 的时候,dp数组里的数值,如下:

代码

class Solution {
    public int integerBreak(int n) {
        int[] dp = new int[n+1];
        dp[2] = 1;
        for(int i=3;i<=n;i++){
            for(int j=1;j<i-1;j++){
                dp[i] = Math.max(dp[i],Math.max((i-j)*j,dp[i-j]*j));
            }
        }
        return dp[n];
    }
}
posted @ 2021-07-01 11:36  当康  阅读(145)  评论(0编辑  收藏  举报