剑指OFFER 13:剪绳子 -动态规划 与 贪心

探讨了如何使用动态规划与贪心算法解决绳子剪裁问题,以实现剪裁后的各段绳子乘积最大化。通过对比两种算法的策略,解析了动态规划的递归特性与贪心算法的局部最优策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:给你一段长度为n 的绳子,请把绳子剪成 m 段,每段长度记作 k1,k2,...km, 要求使得 k1 * k2 * ...km 乘积最大。

思路:动态规划满足的特点:
特点1:求一个问题的最优解,通常是求最大值或最小值问题。
特点2:该问题可以拆分为若干个子问题,该问题的最优解又依赖于子问题的最优解。比如剪长度为5的绳子,依赖的子问题就是长度为1 和 4 子问题,与长度为2 和 3 子问题相比较下的最优解。
特点3:把大问题拆分成若干个小问题,这些小问题之间彼此重复。比如求绳子为5的,与求绳子为6的,重叠子问题就在于,求5时已经算过 4 (1和4),算6时还要算4 (2和4)。
特点4:从上往下分析问题,从下网上求解问题。比如求解为5的绳子,就要去计算1 与4 ,2 与3 ,是由5 才去联想到去计算1 4,2 5,然而代码里面求解是先计算1,2,3,4,

贪心:
贪心算法的要点在于贪心策略,贪心算法的特点是,局部最优解一定能求得总体最优解。
比如这题贪心策略是尽可能多剪长度为3的绳子,即一个数分解成多个3,比分解成其它数要大。这个需要证明。
当 n >= 5时, 2(n-2) > n, 3(n-3) >n ,  同时 , 3(n-3) >= 2(n-2)
注意! 当n ==4 时,2(n-2) > 3(n-3)


import java.util.Scanner;

public class CutShenzi {

	public static void main(String[] args) {
		System.out.println("绳子长度,N=");
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		System.out.println(Dynamic(n));
		//System.out.println(Tanxin(n));
	}
	public static int Dynamic(int len) {
		int max=0;
		if(len <  2) return 0;
		if(len == 2) return 1;
		if(len == 3) return 2;
		int [] arr = new int [len+1];
		arr[0]=0;
		arr[1]=1;
		arr[2] = 2;
		arr[3] = 3;
		for(int i=4;i<=len;i++) {
			for(int j=1;j<=i/2;j++) {
				int tmp = arr[j] * arr[i-j];
				if(max<tmp) max = tmp;  		//穷举找到乘积i最大值
			}
			arr[i] = max;
		}
	/*
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i]+"  ");
		}
		System.out.println("=====================");
		*/
		return arr[len];
	}
	
	public static int Tanxin(int len) {
		if(len <  2) return 0;
		if(len == 2) return 1;
		if(len == 3) return 2;
		//贪心策略,多剪 长度为3的绳子
		int timesof3 = len/3;
		//当长度为4时,应该剪成2*2 > 1*3
		if(timesof3*3+1==len) timesof3--;
		int timesof2 = (len-timesof3*3)/2;
		return (int)Math.pow(3, timesof3) * (int ) Math.pow(2, timesof2);
	}
}

总结:这个题其实就是求一个数分解成若干个数k1,k2,km,,k1+k2+..km = n,并且求这几个k1,k2 ..km 乘积最大的题。
同时要记得动态规划与贪心的区别,动态规划的特点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值