c++使用樸素遞迴演算法(自頂向下遞迴)和動態規劃dp(帶備忘的自頂向下,自底向上)解決鋼條切割及執行例項結果
阿新 • • 發佈:2019-01-25
本博文資料來源於演算法導論第三版
動態規劃有兩種等價實現方法:帶備忘的自頂向下發(topDownWithMemoization),自底向上方法,付出額外的記憶體空間來節省計算時間,是典型的時空權衡,遞迴時會儲存每個子問題的解
長度n與對應價格p關係
1~10的對應最優收益
樸素遞迴之自頂向下方法虛擬碼
c++程式碼
#include <iostream> using namespace std; upDownCutRod(int p[],int n) { if(n==0) return 0; int q=-1; for(int i=0;i<n;++i) q=max(q,p[i]+upDownCutRod(p,n-i-1)); return q; } int main() { int p[10]={1,5,8,9,10,17,17,20,24,30}; int q=upDownCutRod(p,10); cout<<"最優收益值為:"<<q; return 0; }
執行結果
動態規劃自頂向下虛擬碼
c++程式碼實現
#include <iostream> using namespace std; int memorizedCutRodAux(int p[],int n,int r[]) { int q;//最大收益值 if(r[n]>=0) return r[n];//檢查所需值是否已知 if(n==0) q=0;//n=0時不會有收益 else { q=-1; for(int i=0;i<n;++i) q=max(q,p[i]+memorizedCutRodAux(p,n-i-1,r)); } r[n]=q; return q; } memorizedCutRod(int p[],int n) { int r[n+1]; for(int i=0;i<=n;++i) r[i]=-1; return memorizedCutRodAux(p,n,r); } int main() { int p[10]={1,5,8,9,10,17,17,20,24,30}; int q=memorizedCutRod(p,10); cout<<"帶備忘的自頂向下方法的最優收益值為:"<<q; return 0; }
執行結果
自底向上方法虛擬碼
c++程式碼實現
#include <iostream> using namespace std; int bottomUpCutRod(int p[],int n) { int r[n+1];//記錄不同規模子問題的解,這裡是1~10 int q;//記錄收益 r[0]=0; for(int j=1;j<=n;++j) { q=-1;//初始為負,常見的表示未知數的方法 for(int i=1;i<=j;++i) { q=max(q,p[i-1]+r[j-i]);//不再使用遞迴 } r[j]=q; } return r[n]; } int main() { int p[10]={1,5,8,9,10,17,17,20,24,30}; int q=bottomUpCutRod(p,10); cout<<"自底向上方法的最優收益值為:"<<q; return 0; }
執行結果