May——剑指 Offer 14- I. 剪绳子I,II

class Solution:
    def cuttingRope(self, n: int) -> int:
        #尽可能多的3组成,3越大积越大
        if n<3: return 1 
        if n==3: return 2 
        res = 1 
        while n>4: 
            n-=3 
            res*=3 
        return res*n 



        #初始化dp[0],dp[1]都是1
        #表示初始化
        #dp[i]表示已经求解出的子问题的最优解,即长度为i的绳子剪成若干段后的最大乘积。
        #假设分出绳子一段为j,剩余的长度是i-j;分出绳子一段为j,剩余的长度划分最优解为dp[i-j]
        #取两个值的最大即可
        dp = [1]*(n+1) 
        for i in range(2,n+1): 
            for j in range(i): 
                dp[i] = max(dp[i],j*max(i-j,dp[i-j])) 
        return  dp[n]

 题目分析:

  • 数学原理
    • 从数学推论的角度来解释,任何一个大于2的数字,都可以由2和3组成
    • 3越多最终的乘积是越大的,因此想拆一个数字或者减去一段绳子必须让3出现的越多越好
    • 因此就有了第一种解法
  • 动态规划
    • 动态规划的核心思想是将复杂庞大的问题拆分成小的子问题去解决
    • dp[i]表示将i长的绳子拆分后得到最大乘积
    • 边界:dp[2]=1
    • 转移方程:dp[i] = max(dp[i],j*max(i-j,dp[i-j])) 
      • 比如5,拆分成两部分
      • 拆分:{1,4},{2,3}
      • dp[5}和1*4、1*dp[4]、2*3、2*dp[3]进行比较
      • j就是要划分最左边的长度,右边的长度要么直接不划分,要么进行划分,然后再比较大小。

class Solution:
    def cuttingRope(self, n: int) -> int:
        if n==1 or n==0:
            return 0
        if n==2:
            return 1
        if n==3:
            return 2
        res = 1
        while n>4:
            res*=3
            res = res%(1e9+7)
            n-=3
        
        return int(res*n%(1e9+7))

题目分析:

  • 和上一个题目的差别就是要取于,这样动态规划的方程就失效了
  • 因此需要利用迭代法去解决这个问题,并且再每一步迭代中都需要取余 

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值