已知鋼條切割的不同長度對應的不同**如下所示:長度i 1 23 45 67 89 10
**pi 1589101717202430
求輸入長度,輸出最佳的收益。
詳細理論知識見《演算法導論第十五章》 p359
書中給出三個演算法:
一、自頂向下遞迴實現
缺點:當n足夠大時,時間會**性地增長。
偽**:
cut-rod(p,n)
if n==0
return 0
q=-max
for i = 1 to n
q=max(q,p[i]+cut_rod(p,n-i))
return q
其中q初始化為負無窮大(或者任意負數也行)
p為一維陣列代表各種長度的對應最佳方案
c++實現**:
#include //自頂向下遞迴實現
using namespace std;
int p[10] = ;
int cut_rod(int p,int n)
return q;
}int main()
}
二、帶備忘的自頂向下法
引入備忘機制,遞迴解決問題,儲存每個子問題的解。
偽**:
memoized-cut-rod(p,n)
let r[0...n]be a new array
for i = 0 to n
r[i] = -max
return memoized-cut-rod-aux(p,n,r)
memoized-cut-rod-aux(p,n,r)
if r[n]>=0
return r[n]
if n==0
q=0else
q=-max
for i = 1 to n
q = max(q,p[i]+memoized-cut-rod-aux(p,n-i,r))
r[n]=q
return q
和自底向下的遞迴實現類似,僅僅是多提供了乙個陣列作為儲存。效率提高。
c++實現
#include //自頂向下遞迴實現
using namespace std;
int p[10] = ;
int r[10];
int n;
int memoized_cut_rod_aux(int p, int n, int r)
r[n] = q;
return q;
}int memoized_cut_rod(int p, int n)
int main()
}
三、自底向上法
自底向上依賴於「更小的」子問題求解。用兩個迴圈代替遞迴實現,每次所依賴的那些更小的子問題都已求解完畢,結果已經儲存。每個子問題只需求解一次。
偽**:
bottom-up-cut-rod(p,n)
let r[0..n]be a new array
r[0]=0
for j = 1 to n
q = -max
for i = 1 to j
q = max(q,p[i]+r[j-i])
r[j]=q;
return r[n]
c++實現**:
#include //自頂向下遞迴實現
using namespace std;
int p[10] = ;
int r[10];
int n;
int bottom_up_cut_rod(int p,int n)
r[j] = q;
} return r[n];
}int main()
}
附上自底向下重構解(返回最優值以及最優值第一段長度)偽**
memoized-cut-rod-aux(p,n,r)
let r[0..n] and s[0..n] be new arrays
r[0]=0
for j=1 to n
q = -1
for i=1 to j
if q < p[i]+r[j-i]
q = p[i]+r[j-i]
s[j]= i ;
r[j] = -max
return memoized-cut-rod-aux(p,n,r)
總結:一直不理解動態規劃,但是卻在很多oj上看到他的影子,今天在演算法導論上算是收穫頗豐,不過dp依舊是一道跨不過去但非得跨過去的障礙。
加油!
動態規劃 鋼條切割問題
動態規劃與分治法相似,都是通過組合子問題的解來求解原問題。回顧下分治法的原理 它將問題劃分為互不相交的子問題 注意 互不相交 遞迴求解子問題,再將它們的解組合起來,即為原問題的解。但是,動態規劃與分治法不同,有以下幾點 1 對於子問題重疊的情況,分治法則重複求解,不高效。而動態規劃對每個子問題只求解...
動態規劃 鋼條切割問題
一家公司購買長鋼條,將其切割成短鋼條 切割本身沒有成本,長度為i的短鋼條的 為pi。那給定一段長度為n的鋼條和乙個 表pi,求鋼條的切割方案使得收益rn最大。如乙個pi如下 長度i123 4567 8910 pi15 891017 1720 2430 在距離鋼條左端i長度處,我們總是可以選擇切割或者...
動態規劃 鋼條切割問題
動態規劃主要用於求解最優化問題,方法與分治法類似,也是將原問題分解成多個子問題,通過遞迴的方法求解子問題。不同之處就是動態規劃會通過增加程式空間複雜度的方式來將時間複雜度為指數級降低為多項式,通俗的講就是動態規劃會利用陣列記錄下子問題的結果,當再需要計算該子問題時直接呼叫該結果即可,就不用再去計算,...