package 小米oj;
public class 钢条切割 {
public static void main(String[] args) {
int price[] = {1,5,8,9,10,17,17,20,24,30};
System.out.println(cut_rod(12,price));
}
public static int cut_rod(int n,int a[])
{
if(n<=0)
return 0;
int max = -1;
for(int i=0;i<a.length;i++)
{ if(n-i-1>=0)
max = cut_rod(n-i-1,a)+a[i]>max?cut_rod(n-i-1,a)+a[i]:max;
}
return max;
}
}
自顶向下实现,2的n次方的时间复杂度,需要优化,期间有大量的重复运算和多余运算。
虽然代码简单,但太慢。
所以,运算空间换运算时间。
所以
一、带备忘录的自顶向下法
给每个计算过的子问题的最优解做上备录,但是牺牲了一个数组的空间
package 小米oj;
public class 钢条切割 {
public static void main(String[] args) {
int price[] = {1,5,8,9,10,17,17,20,24,30};
int price1[] = new int[1000000];
System.out.println(cut_rod(100,price,price1));
}
public static int cut_rod(int n,int a[],int a1[])
{
if(a1[n]>0)
return a1[n];
if(n<=0)
return 0;
int max = -1;
for(int i=0;i<a.length;i++)
{ if(n-i-1>=0)
max = cut_rod(n-i-1,a,a1)+a[i]>max?cut_rod(n-i-1,a,a1)+a[i]:max;
}
a1[n] = max;
return max;
}
}
二、自底向上求法
从最小的子问题开始,每个子问题只求一次
package 小米oj;
public class 切刚块 {
public static void main(String[] args) {
int price[] = {1,5,8,9,10,17,17,20,24,30};
int price1[] = new int[1000000];
System.out.println(cut_rod(100,price,price1));
}
public static int cut_rod(int n,int a[],int a1[])
{
if(n==0)
return 0;
int max_p = -999;
for(int i=1;i<=n;i++)
{
for(int j=0;j<i&&j<a.length;j++)
{
max_p = a[j]+a1[i-j-1]>max_p?a[j]+a1[i-j-1]:max_p;
}
a1[i] = max_p;
}
return max_p;
}
}
一般情况下第二种稍快一些