剑指offer书(14)剪绳子

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));
	}

}

猜你喜欢

转载自blog.csdn.net/hxl0925/article/details/89393813