343. 整数拆分

版权声明:转载请标明出处「OneDeveloper」 https://blog.csdn.net/OneDeveloper/article/details/79958654

这里写图片描述


1、数学思维

参考:http://www.cnblogs.com/shihaochangeworld/p/5547436.html

public static int integerBreak(int n) {
    if(n <= 3) return n - 1;
    if (n%2==0) {
        int numOf3 = n / 6 * 2;
        int numOf2 = n % 6 / 2;
        return  (int) (Math.pow(3, numOf3) * Math.pow(2, numOf2));
    } else {
        int numOf3 = (n-3)/6*2+1;
        int numOf2 = (n-3)%6/2;
        return (int) (Math.pow(3, numOf3) * Math.pow(2, numOf2));
    }
}

当 n >= 4 时,需要分奇数和偶数的情况:

(1)当 n 为偶数时,就会有 n / 6 * 2 个 3,这里需要注意的是,计算 3 的个数时,不是直接用的 n / 3,而是通过 n / 6 * 2 来间接计算的。因为当 n 为偶数时,n % 3 的结果有 0、1、2 ,当余数为 0、2 时,n / 3 个 3 是最优的(例如 8、12,且 3 的个数为偶数个 ),但是余数为 1 的时候,n / 3 肯定为奇数(因为 偶数 - 1 = 奇数),此时应该从 n / 3 个 3 中分出一个 3 来和 1 组成 4,然后拆分成 2 + 2,才能使结果达到最优。所以直接使用 n / 6 * 2 ,这样求出来的 3 的个数为偶数个,且 n % 6 也为 0 或者偶数 2、4偶数 - 偶数 = 偶数)。

(2)当 n 为奇数时,根据前面的情况,如果直接用 n / 6 (余数为 1、3、5,其中 5 = 3 + 2)计算 3 的个数,当余数为 3、5 时就会少计算一个 3,且当 n 为奇数时,n 拆分得到的 3 的个数一定为奇数个,因此可以转换一下,用 (n-3)/6*2+1 来计算 3 的个数,其中 (n - 3) 就转换为偶数了。


2、动归

参考:https://blog.csdn.net/u013575812/article/details/51194637

public static int integerBreak2(int n) {
    if(n <= 3) return n - 1;
    int[] dp = new int[n + 1];
    dp[1] = 1;
    dp[2] = 2;
    dp[3] = 3;
    for(int i = 4; i <= n; ++i)
    {
        dp[i] = Math.max(2 * dp[i - 2], 3 * dp[i - 3]);
    }
    return dp[n];
}

其中 dp[1]dp[3] 是默认的值,用于后面转移方程的计算,转移方程为:

dp[i] = max(2 * dp[i - 2], 3 * dp[i - 3])

dp[i] 代表 n = i 时,拆分后可获得的最大乘积。

因为当 n > 4 时,n 在拆分后,最优解只包含 3 和 2,其中 2 的个数可能为 0,利用i = 2 + (i - 2) 或者 i = 3 + (i - 3),即 i 如果拆分出一个 2 了,则剩下的数可以根据 dp[i-2] 来直接求出, i 如果拆分出一个 3 了,则剩下的数可以根据 dp[i-3] 来直接求出,再比较两者中的最大值即可。

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页