天天刷leetcode——343整数拆分

整数拆分

题目描述

给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。

解题思路

1. 动态规划

d p [ i ] dp[i] dp[i] 表示正整数 i i i,被拆分为至少两个正整数后的最大乘积。
那么 d p [ 0 ] = d p [ 1 ] = 0 dp[0] = dp[1] = 0 dp[0]=dp[1]=0
假设 i i i首先可以拆成 j j j。则有以下两种情况:

  • i i i分为 j j j i − j i-j ij的,且 i − j i-j ij不能再被分了。此时的乘积就是 j × ( i − j ) j×(i-j) j×(ij)
  • i i i 拆分成 j j j i − j i-j ij的和,且 i − j i−j ij 继续拆分成多个正整数,此时的乘积是 j × d p [ i − j ] j×dp[i−j] j×dp[ij]
    所以, d p [ i ] = m a x ( j × ( i − j ) , j × d p [ i − j ] ) dp[i] =max(j×(i-j),j×dp[i-j]) dp[i]=max(j×(ij),j×dp[ij])。因为j的范围为 ( 1 , i − 1 ) (1,i-1) 1i1, 所以需要遍历j求最大的dp[i]。
    动态转移方程如下:
    dp ⁡ [ i ] = max ⁡ 1 ≤ j < i { max ⁡ ( j × ( i − j ) , j × d p [ i − j ] ) } \operatorname{dp}[i]=\max _{1 \leq j<i}\{\max (j \times(i-j), j \times \mathrm{dp}[i-j])\} dp[i]=1j<imax{max(j×(ij),j×dp[ij])}
    def integerBreak(self, n: int) -> int:
        dp = [0 for i in range(n+1)]
        # print(dp)
        for i in range(2,n+1):
            for j in range(1,i):
                dp[i] = max(dp[i],j * (i-j),j * dp[i-j])
        return dp[n]

在这里插入图片描述
总结:时间复杂度为O(n^2),不咋优秀

2. 用数学方法解题

有推论:将数字n尽可能以因子3等分时,乘积最大。
推理的具体过程见链接: https://leetcode-cn.com/problems/integer-break/solution/343-zheng-shu-chai-fen-tan-xin-by-jyd/.
还没写完。。。

references

[1] https://leetcode-cn.com/problems/integer-break/solution/343-zheng-shu-chai-fen-tan-xin-by-jyd/.
[2] https://leetcode-cn.com/problems/integer-break/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值