package java_jianzhioffer_algorithm;
import java.util.*;
/**
* 题目:长度为n的绳子剪成m段,每段绳子长度记为k[m]
* n,m均大于1
* 请问k[0]*...*k[m]最大乘积可能是多少
* eg:n=8,m=3, 为 2*3*3=18
* @author hexiaoli
*思想:动态规划,找出规律从f(n)递归到f(1),或者f(1)递归到f(n)
* f(n)=max(f(i)*f(n-i))
* o(n^2),o(n)
* 贪婪算法,n<=4时,剪成长度为2的绳子,n>5时,剪成长度为3的绳子,数学方法证明
* o(1)
*/
public class CuttingRope {
public static int cuttingRope1(int length) {
//先输出长度小于等于3的时候f(0)=0,f(1)=0,f(2)=1,f(3)=2
if(length < 2) {
return 0;
}
if(length == 2) {
return 1;
}
if(length == 3) {
return 2;
}
int max = 0;//存储当前乘积最大值
int[] f = new int[length+1];
f[0] = 0;
f[1] = 1;
f[2] = 2;
f[3] = 3;//这里指长度为3的时候
for(int i=4;i<=length;i++) {
max = 0;//f(i)存储当前i乘积最大值
for(int j =1;j<=i/2;j++) {
int temp = f[j]*f[i-j];
if(max < temp) {
max = temp;
f[i] = max;
}
}
}
max = f[length];
return max;
}
public static int cuttingRope2(int length) {
if(length < 2) {
return 0;
}
if(length == 2) {
return 1;
}
if(length == 3) {
return 2;
}
//尽可能剪去长度为3的绳子
int timeOf3 = length/3;
//绳子长度为4时,变为长度为2的绳子
if(length - timeOf3*3 == 1) {
timeOf3 -=1;
}
int timeOf2 =(length-timeOf3*3)/2;
return (int)Math.pow(3, timeOf3)*(int)Math.pow(2, timeOf2);
}
public static void main(String[] args) {
System.out.println("测试用例应该包括0,1,2,3,4,5");
Scanner input = new Scanner(System.in);
int length = input.nextInt();
System.out.println(cuttingRope1(length));
System.out.println(cuttingRope2(length));
}
}
剑指offer书(14)剪绳子
猜你喜欢
转载自blog.csdn.net/hxl0925/article/details/89393813
今日推荐
周排行