题目描述:给你一根长度为n
的绳子,请把绳子剪成整数长的m
段(m
、n
都是整数,n>1
并且m>1
,m<=n
),每段绳子的长度记为k[1],...,k[m]...。请问
k[1]x...xk[m]可能的最大乘积是多少?例如,当绳子的长度是
8时,我们把它剪成长度分别为
2、
3、
3的三段,此时得到的最大乘积是
18。
输入描述:输入一个数n,(2 <= n <= 60)
返回值描述:输出答案
示例1:
输入:
8
返回值:
18
思路及解答:
每个长度的绳子,要么最长的情况是不剪开(长度是本身),要么长度是剪开两端的乘积。因此每个长度length都需要遍历两个相加之后等于length的乘积,取最大值。初始化值 长度为1的值为1,从长度为2开始,每种长度都需要遍历两个字长度的乘积。
Java实现代码如下所示:
public class Solution{
public int cutRope(int target){
if(target <= 1){
return target;
}
int[] nums = new int[target + 1];
nums[1] = 1;
nums[0] = 1;
for(int i = 2 ; i <= target ; i++){
int max = i;
for(int j = 0 ; j <= i/2 ; j++){
int temp = nums[j] * nums[i -j];
if(temp > max){
max = temp;
}
}
nums[i] = max;
}
return nums[target];
}
}
采用动态规划的方法来解题:假设绳子长度为n的最大的长度为f(n),那么如何计算f(n)?
f(n)可能是n,不切分的情况下
f(n)可能是f(n-1)和f(1)的乘积
f(n)可能是f(n-2)和f(2)的乘积
……
因此,要想求f(n),我们必须先把f(n-1),f(n-2)……之类的前面值先求出来,f(1) = 1,这是初始值
Java实现代码如下所示:
public class Solution{
public int cutRope(int target){\
int[] dp = new int[target + 1];
dp[1] = 1;
for(int i = 2 ; i <= target ; i++){
for(int j = i ; j < i ; j++){
dp[i] = Math.max(dp[i], (Math.max(j,dp[j])) * (Math.max(i - j,dp[i -j])));
}
}
return dp[target];
}
}
时间复杂度:O(n^2) 空间复杂度:O(n),需要创建额外的二维数组