LeetCode-剪绳子

博客将问题抽象为整数划分问题,探讨如何将整数拆分为若干正整数之和,使乘积最大。结论是将整数尽量多拆成3,根据对3取模的结果决定2的拆分情况,并从多个方面给出证明,如证明最优解中不包含大于等于5、4和1的数,最多有两个2。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本题可以抽象为整数划分的问题,给我们一个整数,然后我们把它拆分为更小的若干个正整数的和,使得拆分出来的这些正整数乘积最大

结论:将整数N把它分成尽量多的3,如果最后剩下一个2的话,就拆分出来一个2,如果剩下两个2的话就拆分为两个2。如果N%3==0,那就把它拆分为若干个3,如果N%3==1,先拆出两个2,剩下的全部分成3,如果N%3==2,先拆出一个2,剩下的全部分成3。下面给出证明:

N > 0, N = n1 + n2 + ... + nk (假设此时拆出的各个元素,使得最大乘积最大)

(1)假设ni >= 5,我们可以划分出一个3,此时,3 * (ni - 3) 是否一定大于ni呢?

3 * ni - 9 >= ni ? ===> 2 * ni >= 9? 是的,因为ni >= 5。所以,如果ni >= 5,我们从中拆出一个3,那么3 * (ni - 3) >= ni,也就是说,拆完3之后一定是比原来更好的。最优解中如果有>= 5的数,那么最优解中一定包含2、3、4了。

(2)如果ni = 4的话,我们可以把它拆成2 * 2,此时乘积不变,所以最优解中也一定不包含4,那么只包含2和3了。

(3)接着证明这里面最多有两个2。假设这里面有三个2,由于2 * 2 * 2 < 3 * 3,所以这里面也一定不会有>= 3个2,那我们就证明了这里面最多有两个2。那就分为三种情况,模3余1时,两个2,模3余2时,一个2,模3余0时,没有2。

(4)显然不包含1,因为拆出一个1来不会使乘积变大。

class Solution {
public:
    int maxProductAfterCutting(int length) {
        if (length <= 3) return 1 * (length - 1);
        
        int res = 1;
        if (length % 3 == 1) res *= 4, length -= 4;
        if (length % 3 == 2) res *= 2, length -= 2;
        while (length) res *= 3, length -= 3;
        
        return res;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青衫客36

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值