package someLearn;
//钢条切割问题
public class CutRod {
public static int cr(int[] p,int n){
if(n==0){
return 0;
}
int max=-10000;
for(int i=1;i<=n;i++){
if((cr(p,n-i)+p[i])>max){
max=p[i]+cr(p,n-i);
}
}
return max;
}
//自底向上的动态规划。
public static int bottom_up_cut_rod(int[] p,int n){
int[] r=new int[n+1];//用来保存 长度为n的钢条的 最优值
for(int i=0;i<n+1;i++){
r[i]=0;
}
for(int j=1;j<=n;j++){
int max=-1000;
for(int i=1;i<=j;i++){
if(p[i]+r[j-i]>max){
max=p[i]+r[j-i];
}
r[j]=max;
}
}
return r[n];
}
//自顶向下的动态规划
public static int mem_cut_rod(int[] p,int n){
int r[]=new int [n+1];
for(int i=0;i<=n;i++){
r[i]=-10000;
}
return m_c_r(p,n,r);
}
private static int m_c_r(int[] p, int n,int[] r) {
if(r[n]>=0){
return r[n];
}
int max=-1000;
if(n==0){
max=0;
}else{
for(int i=1;i<=n;i++){
if(p[i]+m_c_r(p, n-i, r)>max){
max=p[i]+m_c_r(p, n-i, r);
}
}
r[n]=max;
}
return max;
}
//重构解 不仅计算最大收益 还保存最优解对应的第一段钢条的长度
public static int[][] extend_bottom_up_cr(int[] p,int n){
int r[][]=new int[2][n+1];
r[0][0]=0;
for(int j=1;j<=n;j++){
int max = -10000;
for(int i=1;i<=j;i++){
if(p[i]+r[0][j-i]>max){
max=p[i]+r[0][j-i];
r[1][j]=i;
}
}
r[0][j]=max;
}
return r;
}
public static void print_cr(int[]p ,int n){
int[][] r=extend_bottom_up_cr(p, n);
System.out.println("切除方案:");
while(n>0){
System.out.println(r[1][n]);
n=n-r[1][n];
}
}
public static void main(String[] args) {
int[] p={0,1,5,8,9,10,17,17,20,24,30};
System.out.println(cr(p,9));
System.out.println(bottom_up_cut_rod(p, 1));
System.out.println(mem_cut_rod(p, 10));
print_cr(p, 2);
}
}