1 CUT-ROD(p,n) 2 if n == 0 3 return 0 4 q=負無窮 5 for i = 1 to n 6 q=max(q,p[i]+CUT-ROD(p,n-i)) 7 return q
上面只用了分治策略,這個算法的性能是不好的T(n)=2n,在子問題的求解中不少都是重複的。算法
動態規劃就是避免這些重複。通常有兩個思路1.記錄中間解 性能
1 MEM-CUT-ROD 2 let r[0..n] be a new array 3 for i = 0 to n 4 r[i]=負無窮 5 return MEM-CUT-ROD-AUX(p,n,r) 6 7 MEM-CUT-ROD-AUX(p,n,r) 8 if r[n]>=0 9 return r[n] 10 if n==0 11 q=0 12 else q=負無窮 13 for i=1 to n 14 q=max(q,p[i]+MEM-CUT-ROD-AUX(p,n-i,r)) 15 r[n]=q 16 return q
2.經過對問題求解順序的合理安排,達到避免重複優化
1 BOTTOM-UP-CUT-ROD(p,n) 2 let r[0..n] be a new array 3 r[0]=0 4 for j=1 to n 5 q=負無窮 6 for i=1 to j 7 q=max(q,p[i]+r[j-i]) 8 r[j]=q 9 return r[n]
1 EXTEND-BOTTOM-UP-CUT-ROD(p,n) 2 let r[0..n] and s[0..n] be new arrays 3 r[0]=0 4 for j = 1 to n 5 q=負無窮 6 for i =1 to j 7 if q < p[i]+r[j-i] 8 q=p[i]+r[j-i] 9 s[j]=i 10 r[j]=q 11 return r and s 12 13 PRINT-CUT-ROD-SOLUTION(p,n) 14 (r,s)=EXTEND-BOTTOM-UP-CUT-ROD(p,n) 15 while n >0 16 print s[n] 17 n=n-s[n]
動態規劃真的是個好東西,書中還講了動態規劃在最長公共子序列以及最優二叉搜索樹上的應用,此處不細講。spa
使用動態規劃方法求解的最優化問題應該具有兩個要素:最優子結構和子問題重疊。code