题目描述
给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1],…,k[m]。请问k[0]xk[1]x…xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
用例
输入 | 输出 | 分析 |
---|---|---|
0 | 0 | 不能分割 |
1 | 1 | 不能分割 |
2 | 1 | 分为1,1的两段 |
3 | 2 | 分为2,1的两段 |
4 | 4 | 分为2,2的两段 |
5 | 6 | 分为2,3的两段 |
6 | 9 | 分为3,3的两段 |
7 | 12 | 分为2,2,3的三段 |
8 | 18 | 分为2,3,3的三段 |
9 | 27 | 分为3,3,3的三段 |
10 | 36 | 分为2,2,3,3的四段 |
11 | 54 | 分为2,3,3,3的四段 |
12 | 81 | 分为3,3,3,3的四段 |
13 | 108 | 分为2,2,3,3,3的五段 |
14 | 162 | 分为2,3,3,3,3的五段 |
N >0 N = n1 + n2 + n3+…+nk
结论:要使最后的乘积最大,分出的数有以下特征:
1.只包含2或3;
2.且2的个数不会超过2个
证明:
1.假设 ni >= 5,
3
∗
(
n
i
−
3
)
3*(ni-3)
3∗(ni−3) >= ni? 一定!因为:2*ni >= 9,所以所有分解的数字中不会有超过5的
2.ni = 4, 4=
2
∗
2
2*2
2∗2 所以不会包含4
3.为什么分解2的个数不会超过2呢?因为
2
∗
2
∗
2
2*2*2
2∗2∗2 <
3
∗
3
3*3
3∗3,分解两个三的效果比分解成三个二的效果更佳。
1-归纳法
# -*- coding:utf-8 -*-
class Solution:
def cutRope(self, number):
# write code here
if number == 0:
return 0
elif number in (1, 2):
return 1
elif number == 3:
return 2
return self.subFunction(number)
def subFunction(self, number):
a = []
while number:
if number % 3 == 0:
a.append(3)
number = number - 3
else:
a.append(2)
number = number - 2
maxV = 1
for i in a:
maxV *= i
return maxV
s = Solution()
res = s.cutRope(14)
print(res)
2.贪心算法
class Solution:
def cutRope(self, number):
# write code here
res=1
if number<=1:
return 0
elif number<=2:
return 1
elif number<=3:
return 2
elif number>3:
if number%3==0:
res=3**(number//3)
elif number%3==1:
res=3**(number//3-1)*4
else:
res=3**(number//3)*(number%3)
return res