【算法作业16】LeetCode 343. Integer Break

343. Integer Break

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.

For example, given n = 2, return 1 (2 = 1 + 1); given n = 10, return 36 (10 = 3 + 3 + 4).

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

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

题解:

这道题给定了一个正整数n(2 < n < 59),要求相加能得到n的数字的乘积(不限数字个数)最大。
我刚开始的思路是,对于一个正整数n,肯定是最接近它的一半的两个数字相乘最大,于是就想着简单的不断去除2,直到除2后比4小停止。对于比较大的数字m,就可以直接用它的一半的结果也就是f(n/2) * f(n/2),正好也属于动态规划。刚开始还以为自己挺对的,结果运行到8的时候发现正确答案应该是18,才发现8 = 2 + 3 + 3,2 * 3 * 3 = 18比8 = 4 + 4,4 * 4 = 16还要大,然后就不知道该怎么处理这个问题了。
后来看了别人的答案,发现应该要使得整个式子被分解出的因子们3的个数最多,具体的数学证明可以先假设n被分成x份,那么我们就要得到(n / x) ^ x最大,对它求导得出当x=e时得到最大值,而与e最邻近的两个正整数就是2和3,因此应当把2和3作为因子。而此时我们更倾向于使用3作为因子,是因为当n = 6时,2 * 2 * 2 = 8 < 9 = 3 * 3,也就是说如果一个数可以被拆成两个3之和,就不能把它拆成三个2之和,也就是在它拆出来的因子之中要确保3的个数最大化。
于是这道题虽然归在了动态规划里面但我感觉好像并不一定要用到动态规划……



代码: 

先贴个之前错误的代码吧,引以为戒
class Solution {
public:
    int integerBreak(int n) {
        vector<int> result(n + 1, 0);
        result[2] = 2;
        result[3] = 3;
        result[4] = 4;
        for (int i = 5; i < n + 1; i++)
        {
            int temp = i;
            if (temp % 2 == 0)
                result[i] = result[temp / 2] * result[temp / 2];
            else
                result[i] = result[temp / 2] * result[temp / 2 + 1];
        }
        result[2] = 1;
        result[3] = 2;
        return result[n];
    }
};
        以下是正确的代码
class Solution {
public:
    int integerBreak(int n) {
        if (n == 2)
            return 1;
        else if (n == 3)
            return 2;
        else if (n == 4)
            return 4;
        int result = 1;
        while (n > 4)
        {
            result *= 3;
            n -= 3;
        }
        result *= n;
        return result;
    }
};



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值