题目描述
给你一根长度为 nn 绳子,请把绳子剪成 mm 段(mm、nn 都是整数,2≤n≤582≤n≤58 并且 m≥2m≥2)。
每段的绳子的长度记为k[0]、k[1]、……、k[m]。k[0]k[1] … k[m] 可能的最大乘积是多少?
例如当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到最大的乘积18。
样例
输入:8
输出:18
算法
查资料网上搜看的好多都说是动态规划或贪心算法,表示没看懂,我只能是找规律找出来的。
设f(n)代表长度为n的绳子剪成若干段的最大乘积,如果第一刀下去,第一段长度是i,那么剩下的就需要剪n-i,那么f(n)=max{f(i)*f(n-i)},n取1,2,3,......,n-1。下面开始找规律:
n
i
所有可能切法
n
f(n)
说明
1
不用想了,没得切
2
1
1*1=1
2(不切)
切1刀最大乘积为1,不切
3
1,2
1*2=2*1=2
3(不切)
切1刀最大乘积为2,不切
4
1,3
1*3=3*1=3
4(不切)
切1刀最大乘积为4,不切
2
2*2=4
5
1,4
1*4=4*1=4
2,3
2*3=3*2=6
5
3*2=6
切1刀最大乘积为6
6
1,5
1*f(5)=f(5)*1=1*2*3=6
2,4
2*4=4*2=8
3,3
3*3=9
6
3*3=9
切1刀最大乘积为9
7
1,6
1*f(6)= f(6)*1=1*3*3=9
2,5
2*f(5)=f(5)*2=2*3*2=12
7
3*4=12
切2刀最大乘积为12
3,4
3*4=4*3=12
切1刀最大乘积为12
8
1,7
1*f(7)=f(7)*1=1*3*4=1*2*2*3=12
2,6
2*f(6)=f(6)*2=2*3*3=18
8
3*3*2=18
切2刀最大乘积为18
切2刀最大乘积为18
3,5
3*f(5)= f(5)*3=2*3*3=18
4,4
4*4=16
9
1,8
1*f(8)=f(8)*1=1*2*3*3=18
2,7
2*f(7)=f(7)*2=2*3*4=24
3,6
3*f(6)=f(6)*3=3*3*3=27
9
3*3*3=27
切2刀最大乘积为27
4,5
4*f(5)=f(5)*4=2*3*4=24
可以看出当n>=5时才有必要进行切割,且进行切割时优先考虑3,例如n=8时,4*4<3*3*2,因此,n对3取余后只有0,1,2三种情况,余0说明正好3的倍数,余1时,因为3*1<4,所以我们可以取出一个3凑成4来使乘积更大。
大概就是这个,可能这是最笨的理解方法了φ(>ω<*)
Python3 代码
### Python3 代码
class Solution(object):
def maxProductAfterCutting(self,length):
"""
:type length: int
:rtype: int
"""
if length == 2:
return 1
product = 1
while(length >= 5):
product *= 3
length -= 3
return product * length
最后附上大神们写的动态规划or贪心算法--剪绳子/切割杆,OVER!