剑指offer第14题 动态规划 贪婪算法 剪绳子

动态规划

  • 把大问题分解为小问题,每个小问题有最优解,用小问题的最优解可以组合为大问题的最优解。
  • 适用情况:
  1. 最优解问题
  2. 整体问题的最优解依赖子问题的最优解
  3. 大问题分解为小问题,小问题还有相互重叠的更小的子问题
  4. 从上而下分析问题,从下往上求解问题

贪婪算法

  • 每一步都可以做出一个贪婪的选择得到最优解

题目

长度为n的绳子切分为m段(至少要切一刀)使得每段长度的乘积最大(m,n均为整数),并且返回这个最大的乘积

  • 第一种解法:动态规划(把切分为多段分解为切分为2段的问题)
  • 分析:
  1. 切一刀分为两段(左和右)。
  2. 左右两段也是切一刀(左和右),乘积最大(大问题分解为小问题)。
  3. 最终的情况是长度为2的绳子切分为了两个长度为1的段,乘积f(2)=1。
  • 切为两段的话:切分位置是在1到n-1,乘积为f(n)=f(i)*f(n-i)
代码实现
  • 动态规划
public int maxOfShengzi(int length) {
		if(length<2) {
			return 0;
		}
		if(length==2) {
			return 1;
		}
		if(length==3) {
			return 2;
		}
	
		//小问题的最优解存放在数组中(把长度为i的绳子分为若干段之后乘积的最大值,不规定必须切一刀)
		int[] bestSolution=new int[length+1];
		bestSolution[0]=0;
		bestSolution[1]=1;
		bestSolution[2]=2;
		bestSolution[3]=3;
		int max=0;

		//i表示的是绳子的长度,j表示的是切分位置(j=i/2的时候相当于后半段的0,即不切分)
		for(int i=4;i<=length;i++) {
			max=0;
			for(int j=1;j<=i/2;j++) {
				int chegnjis=bestSolution[j]*bestSolution[i-j];
				if(chengjis>max) {
					max=chengjis;//max表示的是最大的乘积
				}
				bestSolution[i]=best;//把小问题的最优解存放在最优解数组里面
			}
		}
		 max=bestSolution[length];
		 return max;
	}
  • 贪婪算法
    尽可能多切3,剩下绳子长度为4时,切分为2*2.(至少切一刀)
    3(n-3)>=2(n-2)
public static int maxOfShengzi(int length) {
		if(length<2) {
			return 0;
		}
		if(length==2) {
			return 1;
		}
		if(length==3) {
			return 2;
		}
		//尽可能多的剪为3的段
		int timeOf3=length/3;
		int timeOf2=0;
		//绳子最后一段为4时,剪成2段2
		if(length-timeOf3*3==1) {
			timeOf3-=1;
			timeOf2=(length-timeOf3*3)/2;
		}
		//最后一段为2,2的次数为1
		else {
			timeOf2=1;
		}
		return (int)(Math.pow(3,timeOf3))*(int)(Math.pow(2,timeOf2));
	}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值