剑指offer:剪绳子(动态规划和贪心)

1. 题目描述

给你一根长度为n绳子,请把绳子剪成m段(m、n都是整数,n>1并且m≥1)。每段的绳子的长度记为k[0]、k[1]、……、k[m]。k[0]k[1]…*k[m]可能的最大乘积是多少?例如当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到最大的乘积18。

2. 思路

2.1 动态规划

动态规划,先自上而下分析,在长度为n的绳子所求为f(n),剪下一刀后剩下的两段长度是i和n-i,在这个上面还可能继续减(子问题),所以:
f(n)=max(f(i)×f(n−i)),i

然后自下而上的解决问题,可以从f(1)开始向上计算并保存,最终获得f(n)的值。
由于当i大于n//2时,就不用在计算了,重复计算因此实际上:
在这里插入图片描述

动态规划从之前的最优解找到当前的最优解,max(n)=max(1...n-1)    需要存储之前的max(1),max(2)...max(n-1)

 

2.1 动态规划代码

def cutRope(length):
    if length == 0:
        return 0
    if length == 1:
        return 1
    if length == 2:
        return 2
    if length == 3:
        return 3
    if length == 4:
        return 4
    result = [0,1,2,3]
    for i in range(4,length+1):
        max = 0
        for j in range(1,i//2+1):
            temp = result[j] * result[i-j]
            if temp > max:
                max = temp
        result.append(max)
    return result[length]
print(cutRope(8))
# 输出结果为18

2.2 贪心法

在这里插入图片描述
等号在n=5时成立。
所以应把绳子剪成尽量多的3,让剩下的都是2这样的组合。

2.2 python 代码

def cutRope(length):
    if length <= 4:
        return length
    timeOfThree = length // 3
    if length - timeOfThree * 3 == 1:  
    # 如果减去3,还剩下4,这时候就不能在减去3了,2*2 > 3 * 1
        timeOfThree -= 1
    timeOfTwo = (length - timeOfThree * 3) // 2
    return pow(3,timeOfThree) * pow(2,timeOfTwo)
print(cutRope(8))
# 输出结果为:18
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值