【代码随想录day24】整数拆分

文章讨论了如何使用动态规划方法解决一个关于将正整数n拆分成k个部分以求乘积最大的问题。通过定义dp数组来存储每个数拆分后的最大乘积,文章详细介绍了算法过程和一个Python实现的Solution类。

题目

给定一个正整数 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。

提示:

  • 2 <= n <= 58

代码

说实话这题的递推公式真的挺难想的。

因为题目要求必须拆分,所以我们不用考虑不拆分的情况。如果拆分的话,我们试想一下每次拆分的情况是怎样的?

  1. 只拆成两个数,算一下乘积
  2. 先拆一个出来,剩下的还能拆,但是拆多少个我不知道

总共就只能拆成这两种情况,那么接下来对于上面情况1要考虑的是我们拆成哪两个数?我也不知道,就用j遍历所有情况看看那个乘积最大就是哪个呗。对于情况2,拆一个同样是用j遍历所有情况,剩下的咋拆?用dp数组拆,可以在之前拆的时候用dp数组记录乘积最大值,这样剩下咋拆就可以通过查dp数组找到最大乘积了。

因此定义dp[i]为数i拆分成至少两个数所能得到的最大乘积。初始化dp[2]=1,然后两层for循环,因为我们要求的是dp[n],所以外层遍历i应该从3~n+1;内层遍历应该是j从1~n,代表把i拆分成一个j和i-j(第一种情况)或者j和dp[i-j](第二种情况)。

class Solution:
    def integerBreak(self, n: int) -> int:
        dp=[0 for _ in range(n+1)]
        dp[2]=1

        for i in range(3,n+1):
            for j in range(1,n):
                dp[i] = max(dp[i],j*(i-j),j*dp[i-j])
        return dp[n]

这里j的终止条件可以优化成i//2+1,不过我一直没想明白为什么可以这样,是怎么知道当j超过i//2+1时dp[i]一定没有更大的值呢??有知道的大佬欢迎评论,让我学习一下,感谢!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小小的香辛料

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

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

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

打赏作者

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

抵扣说明:

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

余额充值