3.4 切木材问题(Rod-cutting problem)
3.4.1 问题描述
给一个长度为17的木材,可以切成小段卖出,价格根据小段的长度不同而不同。如何通过切成小段卖出尽可能高的总价钱?
3.4.2 算法思路
总体思路:
① 假如我们只有1米长的木材,那么就直接按1米的价格卖;
② 假如我们有2米长木材,那么可以切成两段卖(1+1=2元)或者直接按2米卖(4元),所以两米时我们不切直接卖;
③ 假如我们有3米,那么我们可以直接按3米卖(5元),或者切成一段1米和一段2米(1+4=5元),此时,两种方案都行,都能取到最大收益5元。*注意:这里不能够切成三段1米卖,因为一旦有2米,我们就直接按2米卖获得的收益最高,所以不能把2米再切成两段1米。*这就是我们解法的关键点,我们后面一旦遇到2米,就直接看Length=2时的value,它代表着2米的最高利益。
依此类推…
④ 假如我们有10米,那么可以直接10米卖(30元)或者切成1米和9米(1+24=25元),或者切成2米和8米(4+20=24元),…,或者5米和5米(10+10=20元),把所有可能进行比较,最终选择其中价值最高的直接10米卖也就是,30元。
一旦超过10米之后,就没有直接卖的价格了,此时就只需要比较切开卖法的价格。
动态规划思想:
- 问题分阶段:把length=n的大问题,分为了一个个小问题
- 阶段有依赖:当我们算到后面大长度的时候,一旦出现某个小长度,我们就可以直接去看对应长度的value值,它代表着这个长度的最大收益,当我们在处理大问题时,都依赖于之前小问题的解。
- 依赖有重合:当我们在处理大长度的时候,就不用重复计算小长度的买法,避免了重复计算。
3.4.3 表格法代码实现
//表格法
public static int getValue(int[] cut_value,int rod_length){
int[] rod_value=new int