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

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时,就不用在计算了,重复计算因此实际上:
在这里插入图片描述

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

猜你喜欢

转载自blog.csdn.net/ggdhs/article/details/92795204