题目描述
给你一根长度为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
。、
示例
输入一个数n,意义见题面。(2 <= n <= 60)
输入: 8
输出: 18
分析
动态规划
如果要求一个问题的最优解
,而且该问题能分成若干个子问题
,整体问题的最优解依赖于子问题的最优解,可以考虑用动态规划
解决。
动态规划一般是自顶向下思考
,自底向上实现的,为了避免计算子问题时重复,可以将子问题的结果通过维护一张二维表
来实现。
状态转移方程
:
边界
:
时间复杂度
: O(
)
空间复杂度
: O(n)
注意
- 这里的
边界条件
却不是
对应输入时的输出
。 - 当前阶段状态的值,与前面
所有状态都有关系
,所以只能通过维护二维表
来实现,不能通过维护几个变量
来实现。
贪心算法
首先,
的时候,我们可以证明:
也就是说,当绳子剩下的长度大于或者等于 5 的时候,我们就把它剪成长度为 3 或者 2 的绳子段。
此外:
因此我们要尽量尽可能地多剪长度为 3 的绳子段。
时间复杂度
: O(1)
空间复杂度
: O(1)
代码
动态规划
# -*- coding:utf-8 -*-
class Solution:
def cutRope(self, number):
# write code here
if number==2:
return 1
if number==3:
return 2
dp = [0, 1, 2, 3]
for i in range(4, number+1):
maxNum = 0
for j in range(1,i//2+1):
temp = dp[j]*dp[i-j]
if maxNum<temp:
maxNum = temp
dp.append(maxNum)
return dp[number]
贪心算法
# -*- coding:utf-8 -*-
class Solution:
def cutRope(self, number):
# write code here
if number<2:
return 0
if number==2:
return 1
if number==3:
return 2
if number==4:
return 4
timesOf3 = number//3 #多剪3
if number-3*timesOf3 == 1: #2*2>3*1
timesOf3 -= 1
timesOf2 = (number-3*timesOf3)//2 #剩下 4,或者 2 时剪 2
return pow(3, timesOf3)*pow(2, timesOf2)