package org.loda.dynamic;
import org.junit.Test;
/**
*
* @ClassName: RodCutting
* @Description: 钢条切割
*
* 动态规划问题
*
* 给定一段长度为n英寸的钢条和一个价格表Pi,求切割钢条的方案,使得销售收益Rn最大
*
* @author minjun
* @date 2015年5月17日 下午12:54:46
*
*/
public class RodCutting {
/**
* 记录所有价格表
*/
private int[] p={1,5,8,9,10,17,17,20,24,30};
//存储之前计算的最优价钱,初始值默认为0
private int[] r;
//存储最优价钱时所切割的第一段的长度
private int[] s;
@Test
public void cutting(){
int n=8;
long start=System.nanoTime();
cutting(n);
System.out.println("长度为"+n+"英寸切割的最大收益为"+r[n]);
System.out.println("切割的两段分别为:"+s[n]+","+(n-s[n]));
long end=System.nanoTime();
System.out.println("时间消耗:"+(end-start)/1000000.0+"毫秒");
}
private void cutting(int n) {
r=new int[n+1];
s=new int[n+1];
//记录第一段切割长度为i时计算过程的数值
for(int i=1;i<=n;i++){
//假设第一段切割长度为i的最大收益为max,为它取个哨兵量的值,即为最小整数
int max=Integer.MIN_VALUE;
//不断切割以尝试获取最大收益
for(int j=1;j<=i;j++){
//本次切割后收益更多,就取为本次切割的收益为最大收益,并将本次切割的第一段的长度设为最优切割长度
if(max<p[j-1]+r[i-j]){
max=p[j-1]+r[i-j];
s[i]=j;
}
}
//完成所有的切割尝试之后,会统计出最优的切割方案所获取的收益,将该收益记录为长度n的最优收益
r[i]=max;
}
}
}
输出结果为:
长度为8英寸切割的最大收益为22
切割的两段分别为:2,6
时间消耗:0.386708毫秒