1. 程式人生 > >動態規劃經典問題切鋼條

動態規劃經典問題切鋼條

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;
		}
}

一般情況下第二種稍快一些