[LeetCode] 343. Integer Break

Medium

Given a positive integer n, break it into the sum of at least two positive integers and maximize the product of those integers. Return the maximum product you can get.

Example 1:

Input: 2
Output: 1
Explanation: 2 = 1 + 1, 1 × 1 = 1.

Example 2:

Input: 10
Output: 36
Explanation: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36.

Note: You may assume that n is not less than 2 and not larger than 58.

 

题目大意:每个正整数都能拆分成至少两个大于零的数之和,给出一个正整数n,求出有这个正整数拆分出的数字的最大乘积。

 

方法:

因为不限制拆分的数字个数,所以一个正整数可以有很多种拆分方式,如果每一种情况都去计算乘积,然后比较得出最大值一定会浪费很多时间。我们考虑动态规划的方法。每个数字都可以拆分成两个数字,然后这两个数字再拆分成更小的两个数字,直至数字为2,因为数字2只有一种拆分情况,可将其设为初始边界条件。这样我们就不用考虑拆分成多个数字的情况,只要保留较小数字的结果来表示较大数字的结果就好了。然后我们对数字进行拆分来观察变化规律:

2 1*1 1
3 2*1 2
4 2*2 4
5 3*2 6
6 3*3 9
7 3*4 12
8 6*2 18
9 6*3 27
10 6*4 36
11 6*5 54
12 6*6 81
13 6*7 108
14 12*2 162

 

我多写个几个例子,因为直到这么多例子我才发现了一个规律,这里需要先注意一下,表中写的乘积的两个数字不是直接将两数相乘,这两个数字是可以继续拆分的,我们已知较小数字的结果,那么我们用他们的结果相乘就是我们的结果了。

我们将2作为初始条件,5及其以后的数字都可以用3(和3的倍数)乘以一个数字表示,比如说5~7这部分就是3*m,m的范围是2~(3+1),8~13这部分是6*m,m范围是2~(6+1),以此类推。2和3是最基础的数字,他们可以组合出所有单双数。因为2和3的结果比本身要小,所以在用小数字结果计算大数字结果的时候要注意判断,选择最大的那个数参与计算。

数字3和4从2得来,分别乘以1和2。由这些规律我们可以维护一个大小为n+1的向量dp,n的结果就是dp[n]。代码如下:

class Solution {
public:
    int integerBreak(int n) {
        vector<int> dp(n + 1, 0);
        dp[2] = 1;
        int level = 2, cur = 1;
        int p = 0;
        for (int i = 3; i <= n; ++i) {
            if ((level == 2 && cur<=level) || (level > 2 && cur <= level + 1)) {
                dp[i] = max(dp[level],level) * max(dp[cur],cur);
                cur++;
            }
            else {
                level = 3 * pow(2, p++);
                cur = 2;
                i--;
            }
        }
        return dp[n];
    }
};

 

 

看到网上的博主分析,每个数字都拆分出3,然后直到剩下的数字是2或者3为止。也就是从5开始,每个数的结果就是数字中包含的3个个数个3相乘,然后乘以剩下的数中包含的2的个数个2相乘。

代码如下:

class Solution {
public:
    int integerBreak(int n) {
        if(n==2 || n==3)return n-1;
        if(n==4)return n;
        n-=5;
        return (int)pow(3,n/3+1)*(n%3+2);
    }
};

 

 

posted @ 2019-12-13 14:56  程嘿嘿  阅读(136)  评论(0编辑  收藏  举报