343--整数拆分(数学+dp)

题目

给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化。

返回 你可以获得的最大乘积 。

示例 1:

输入: n = 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1。
示例 2:

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

链接:https://leetcode.cn/problems/integer-break

动态规划的解答

  • 也就是每一个数字n都要拆分为大于2个数目的数字,那么每一个数字都得有一个循环,从2开始一直到这个数字n,在这个循环中从1开始计算这个数字拆分后的乘积的最大值。
    创建数组 \textit{dp}dp,其中 \textit{dp}[i]dp[i] 表示将正整数 ii 拆分成至少两个正整数的和之后,这些正整数的最大乘积。特别地,00 不是正整数,11 是最小的正整数,00 和 11 都不能拆分,因此 \textit{dp}[0]=\textit{dp}[1]=0dp[0]=dp[1]=0。

当 i \ge 2i≥2 时,假设对正整数 ii 拆分出的第一个正整数是 jj(1 \le j < i1≤j<i),则有以下两种方案:

将 ii 拆分成 jj 和 i-ji−j 的和,且 i-ji−j 不再拆分成多个正整数,此时的乘积是 j \times (i-j)j×(i−j);

将 ii 拆分成 jj 和 i-ji−j 的和,且 i-ji−j 继续拆分成多个正整数,此时的乘积是 j \times \textit{dp}[i-j]j×dp[i−j]。

因此,当 jj 固定时,有 \textit{dp}[i]=\max(j \times (i-j), j \times \textit{dp}[i-j])dp[i]=max(j×(i−j),j×dp[i−j])。由于 jj 的取值范围是 11 到 i-1i−1,需要遍历所有的 jj 得到 \textit{dp}[i]dp[i] 的最大值,因此可以得到状态转移方程如下:

\textit{dp}[i]=\mathop{\max}\limits_{1 \le j < i}{\max(j \times (i-j), j \times \textit{dp}[i-j])}
dp[i]=
1≤j<i
max

最终得到 \textit{dp}[n]dp[n] 的值即为将正整数 nn 拆分成至少两个正整数的和之后,这些正整数的最大乘积。

解答

点击查看代码
public class ThreeFourThree {
    public static int integerBreak(int n) {
       int [] dp=new int[n+1];
       for(int i=2;i<=n;i++){
           int max=0;
           for(int j=1;j<i;j++){
               max=Math.max(max,Math.max(j*(i-j),j*dp[i-j]));
           }
           dp[i]=max;
       }
       return dp[n];
    }
}

数学解法

对于每一个数到最后都能拆分为最小的数字,那么考虑最小的那个数字2和3的组合,而 222 < 33 ,22 > 31 ;因此拆分后所有的 2 三个一组合并为 33,剩下的2保留,最后计算乘积即可。

点击查看代码

class Solution {
    public int integerBreak(int n) {
        if (n <= 3) {
            return n - 1;
        }
        int quotient = n / 3;
        int remainder = n % 3;
        if (remainder == 0) {
            return (int) Math.pow(3, quotient);
        } else if (remainder == 1) {
            return (int) Math.pow(3, quotient - 1) * 4;
        } else {
            return (int) Math.pow(3, quotient) * 2;
        }
    }
}

posted @ 2022-05-12 10:40  是徐洋洋呀  阅读(154)  评论(0编辑  收藏  举报