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(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