题目描述:
给你一根长度为 n 绳子,请把绳子剪成 m 段(m、n 都是整数,2≤n≤58 并且 m≥2)。 每段的绳子的长度记为k[0]、k[1]、……、k[m]。k[0]k[1] … k[m] 可能的最大乘积是多少?
例如:当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到最大的乘积18。
分析:
书上说的有数学规律:(看注释)
# 方法一:贪婪算法
def maxProductAfterCutting(length):
if length == 2: # 这3个特殊的长度,直接求出返回值
return 1
elif length == 3:
return 2
elif length == 4:
return 4
c=[]
while length >= 5: # 由数学计算得出,当长度大于5时候,每段长3,乘积最大
length-=3 # 巧的是,如果最后剩4,分成2*2 乘积最大,但是4正好是2*2的值。巧!
c.append(3)
return 3**len(c)*length
maxProductAfterCutting(6)
方法二:动态规划。把前边的都求出来。
(从此题首次接触动态规划。)
# 方法二:动态规划
def dynamic_programming(n):
if n==2: # 这3个特殊的长度,直接求出返回值
return 1
if n==3:
return 2
if n==4:
return 4
tem_lis = [0,0,2,3,4] # 这个列表的前两个数无所谓,因为根本用不到
for i in range(5,n+1): # 外循环:绳子长度从5到n 注意range()前闭后开。
maxx = 0
for j in range(2,i//2+1): # 内循环:所有可能的组合:2,3,4...中间值
tem = tem_lis[j]*tem_lis[i-j] # i-j 为另一段长度
if tem > maxx:
maxx = tem # maxx存放乘积最大的值
tem_lis.append(maxx) # tem_list中存储的是所有的可能绳子长度的解
#print(tem_lis)
return tem_lis[n]
dynamic_programming(8)