動態規劃經典問題切鋼條
阿新 • • 發佈:2019-01-03
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;
}
}
一般情況下第二種稍快一些