题目
题目描述
给你一根长度为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
题解
- 暴力递归法(时间复杂度太高容易超时)
public class Solution {
public int cutRope(int target) {
if(target==2) return 1;
else if(target==3) return 2;//这两种情况需要特判。
else{
return ac(target);
}
}
public int ac(int n){
if(n<=4) return n;//此时不分的话是最大的;绳子的长度为4时刚好凑巧满足不分和分最大一样长,故省略cutRope函数中的target=4特判。
int fal = 0;
for(int i=1;i<n;i++){
fal = Math.max(fal,i*ac(n-i));
}
return fal;
}
}
- 记忆化递归
设立一个数组来记录一下每次递归重复递归的部分即可
import java.util.*;
public class Solution {
static int j[] = new int[66];
public int cutRope(int target) {
Arrays.fill(j, 0);
if(target==2) return 1;
else if(target==3) return 2;
else{
return ac(target);
}
}
public int ac(int n){
if(n<=4) return n;
if(j[n]!=0){
return j[n];
}
int fal = 0;
for(int i=1;i<n;i++){
fal = Math.max(fal,i*ac(n-i));
}
j[n] = fal;
return fal;
}
}
- 动态规划法
总体就是将记忆化递归总结起来,区别不大
import java.util.*;
public class Solution {
static int j[] = new int[66];
public int cutRope(int target) {
Arrays.fill(j, 0);
if(target==2) return 1;
else if(target==3) return 2;
else{
for(int i=1;i<=4;i++) j[i] = i;
for(int i=5;i<=target;i++){
for(int k=1;k<i;k++){
j[i] = Math.max(j[i],k*j[i-k]);
}
}
}
return j[target];
}
}