题14:剪绳子
给你一根长度为n的绳子,请把绳子切为m段(m>1,n>1,且为整数),每段绳子记为k[0],k[1]…k[m]。
求出k[0]k[1]…*k[m]的最大值。
例如:当绳子的长度为n=8时,可以剪为2,3,3,最大值为18
动态规划求解:
- 假设方法f(n)就是获取长度为n的绳子的最大乘积
- 从上至下,剪第一刀的时候,有 n - 1 种方式,f(n) = max(f(i) * f(n-i)),有很多重复计算的递归式
- 从下至上,我们可以先获取f(2)、f(3),就可以再获取到f(4)、f(5),直到获得f(n)
public class CutRope {
public static int cutRope(int length){
//当绳子小于4的时候
if(length < 2){return 0;}
if(length == 2){return 1;}
if(length == 3){return 2;}
//当绳子大于等于4
//存放最优值,这个0,1,2,3代表是不可再切
int[] result = new int[length + 1];
result[0] = 0;
result[1] = 1;
result[2] = 2;
result[3] = 3;
int max = 0;
//从4开始往上求每段的最优值
for(int i = 4;i <= length;i++){
max = 0;
//每一段小长度的绳子切刀的位置,相当于切一刀分为两半,求两半的乘积,因为更小的长度已经求好了
for(int j = 1;j <= i/2;j++){
int tem = result[j]*result[i-j];
max = max < tem ? tem : max;
}
result[i] = max;
}
max = result[length];
return max;
}
//test
public static void main(String[] args) {
System.out.println(cutRope(-1));
System.out.println(cutRope(0));
System.out.println(cutRope(1));
System.out.println(cutRope(2));
System.out.println(cutRope(3));
System.out.println(cutRope(4));
System.out.println(cutRope(5));
System.out.println(cutRope(6));
System.out.println(cutRope(7));
System.out.println(cutRope(8));
}
}