class Solution:
def cuttingRope(self, n: int) -> int:
#尽可能多的3组成,3越大积越大
if n<3: return 1
if n==3: return 2
res = 1
while n>4:
n-=3
res*=3
return res*n
#初始化dp[0],dp[1]都是1
#表示初始化
#dp[i]表示已经求解出的子问题的最优解,即长度为i的绳子剪成若干段后的最大乘积。
#假设分出绳子一段为j,剩余的长度是i-j;分出绳子一段为j,剩余的长度划分最优解为dp[i-j]
#取两个值的最大即可
dp = [1]*(n+1)
for i in range(2,n+1):
for j in range(i):
dp[i] = max(dp[i],j*max(i-j,dp[i-j]))
return dp[n]
题目分析:
- 数学原理
- 从数学推论的角度来解释,任何一个大于2的数字,都可以由2和3组成
- 3越多最终的乘积是越大的,因此想拆一个数字或者减去一段绳子必须让3出现的越多越好
- 因此就有了第一种解法
- 动态规划
- 动态规划的核心思想是将复杂庞大的问题拆分成小的子问题去解决
- dp[i]表示将i长的绳子拆分后得到最大乘积
- 边界:dp[2]=1
- 转移方程:dp[i] = max(dp[i],j*max(i-j,dp[i-j]))
- 比如5,拆分成两部分
- 拆分:{1,4},{2,3}
- dp[5}和1*4、1*dp[4]、2*3、2*dp[3]进行比较
- j就是要划分最左边的长度,右边的长度要么直接不划分,要么进行划分,然后再比较大小。
class Solution:
def cuttingRope(self, n: int) -> int:
if n==1 or n==0:
return 0
if n==2:
return 1
if n==3:
return 2
res = 1
while n>4:
res*=3
res = res%(1e9+7)
n-=3
return int(res*n%(1e9+7))
题目分析:
- 和上一个题目的差别就是要取于,这样动态规划的方程就失效了
- 因此需要利用迭代法去解决这个问题,并且再每一步迭代中都需要取余