343. Integer Break

本文探讨了LeetCode上的整数拆分问题,提出两种解决方案:一是尽量将整数拆分为3来获得最大乘积;二是采用动态规划方法。通过数学证明解释了为何拆分为3最有效,并给出了具体算法实现。

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

https://leetcode.com/problems/integer-break/description/

题目:整数拆分。

解法一 思路:拆成尽量多的3。

证明:
这里写图片描述 >= 这里写图片描述
得:当把输入的n拆分成几个相等的数时它们的积最大。

那么问题来了,拆分成几个呢?

为了方便使用导数,我们先假设我们可以把n拆分成实数。那么设每一个数为x,则一共有n/x个数。

设它们的积为f(x),则f(x)=x(n/x),那么怎么求f(x)最大值呢?求导数!

f′(x)=(n/x2) * x(n/x) * (1-lnx)

当x=e时取极大值。

而我们题目里规定x为整数,那么我们只需要取的x越靠近e越好。所以取3是最好的,如果取不到3就取2。

幂运算复杂度为O(lgn),所以这个算法复杂度为O(lgn)。

class Solution {
public:
    int integerBreak(int n) {
    if(n == 2) return 1;
    if(n == 3) return 2;
    if(n == 4) return 4;
    int ret = 1;
    while( n>4 )
    {
        ret *= 3;
        n -= 3;
    }
    return ret * n;
    }
};

解法二: dp

令dp[n]为n对应的最大积。

那么递推方程就是:dp[n]=max(i*dp[n-i],i*(n-i))(其中i从1到n-1)。

边界:dp[2]=1;

class Solution {
public:
    int integerBreak(int n) {
      int dp[n+1];
        dp[1]=1;
        dp[2]=1;
       for(int i=3;i<=n;i++){
            dp[i]=-1;
            for(int j=1;j<i;j++){
                dp[i]=max(j*dp[i-j],max(dp[i],j*(i-j)));
            }
        }
        return dp[n];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

计算机的小粽子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值