utf8gbsn
先來看看問題,加入我們有乙個**表
length(i) 1 2 3 4 5 6 7 8 9 10
price(p
ip_i
pi) 1 5 8 9 10 17 17 20 24 30
那麼,我們現在有一根剛才長度為n
nn,你是乙個加工商,需要把長度為n
nn的剛才切割為(1,
2,..
.,10)
(1,2,...,10)
(1,2,.
..,1
0)長度賣出去。問怎麼才能賣出最高的**。
我們先來看看乙個遞迴解法。也就是把問題分治,
當乙個剛才被切割為2部分的時候。我們可以分別計算這兩部分的最大收益,然後得出這種分法的最大收益。遞迴而來,最終可以得到最終的收益。
cut-rod(p, n)
if n == 0
return 0
q = - infinity
for i = 1 to n
q = max(q, p[i]+cut-rod(p, n-i))
return q
因為是乙個遞迴演算法我們用呼叫的次數來衡量演算法的複雜度。那麼首先,我們先來看看
這個可以用歸納法求出來,也就是說
t (n
−1)=
2n−1
,t(0
)=1,
t(1)
=2→t
(n)=
2n
t(n-1)=2^,t(0)=1,t(1)=2\rightarrow t(n) = 2^n
t(n−1)
=2n−
1,t(
0)=1
,t(1
)=2→
t(n)
=2n2n=
1+2n
−1+2
n−2+
...+
23+2
2+21
+1
2^n=1+2^+2^+...+2^3+2^2+2^1+1
2n=1+2
n−1+
2n−2
+...
+23+
22+2
1+1所以,呼叫是指數級別的的增長。比如當n=40
n=40
n=40
時,程式就需要執行數分鐘之久。所以,遞迴解法不是乙個可取的演算法。
我們仔細來分析一下,問題。對於上面提到的遞迴演算法,實際上重複計算了很多東西。比如,當n=5
n=5n=
5的時候。
第一次迴圈中
( 1,
cut−
rod(
p,4)
),(2
,cut
−rod
(p,3
)),(
3,cu
t−ro
d(p,
2)),
...,
(5,c
ut−r
od(p
,0))
(1, cut-rod(p, 4)),(2, cut-rod(p, 3)),(3, cut-rod(p, 2)),...,(5, cut-rod(p, 0))
(1,cut
−rod
(p,4
)),(
2,cu
t−ro
d(p,
3)),
(3,c
ut−r
od(p
,2))
,...
,(5,
cut−
rod(
p,0)
)把(1,c
ut−r
od(p
,4))
(1, cut-rod(p, 4))
(1,cut
−rod
(p,4
))展開(1,
cut−
rod(
p,3)
),(2
,cut
−rod
(p,2
)),.
..,(
4,cu
t−ro
d(p,
0)
)(1, cut-rod(p, 3)),(2, cut-rod(p, 2)),...,(4, cut-rod(p, 0))
(1,cut
−rod
(p,3
)),(
2,cu
t−ro
d(p,
2)),
...,
(4,c
ut−r
od(p
,0))
可以看到,第一步中第二項和第二步中的第一項的
cut-rod是一模一樣的。但是因為是遞迴。實際上我們對這個函式計算了兩次。而動態規劃的核心就是如何把已經計算的東西快取起來,讓計算更高效。
自頂向下的方法。
cut-rod(p, n)
let r[0..n] be a new array
for i = 0 to n
r[i] = - infinity
return cut-rod-aux(p, n, r)
這裡引入了乙個輔助函式
cut-rod-aux(p, n, r)
if r[n] > = 0
return r[n]
if n == 0
q = 0
else q = - infinity
for i = 1 to n
q = max(q, p[i] + cut-rod-aux(p, n-i, r))
r[n] = q
return q
更為簡單 cut-rod(p, n)
let r[0..n] be a new array
r[0] = 0
for j = 1 to n
q = - infinity
for i = 1 to j
q = max(q, p[i]+r[j-1])
r[j] = q
return r[n]
由於我們使用了兩層迴圈所以複雜度為 θ(n
2)
\theta(n^2)
θ(n2
)ex-cut-rod(p, n)
let r[0..n] and s[0..n] be new arrays
r[0] = 0
for j = 1 to n
q = - infinity
for i = 1 to j
if qprint-cut-rod(p,n)
(r,s) = ex-cut-rod(p, n)
while n > 0
print s[n]
n = n - s[n]
至此,動態規劃解決鋼管切割問題,就完成了。 動態規劃 什麼是動態規劃?
先來看看 資訊學奧賽一本通第5版 是怎麼說的 動態規劃程式設計是對解最優化問題的一種途徑 一種方法,而不是一種特殊演算法。不像前面所述的那些搜尋或數值計算那樣,具有乙個標準的數學表示式和明確清晰的解題方法。動態規劃程式設計往往是針對一種最優化問題,由於各種問題的性質不同,確定最優解的條件也互不相同,...
mysql動態規劃 動態規劃
動態規劃 能夠動態規劃的問題具有以下特點 可分解成規模更小的子問題 子問題的結果可復用 關鍵是要理解狀態轉移方程的含義就好啦!數字三角形 問題描述 在數字三角形尋找從頂到底的路徑,使得路徑經過的數字之和最大。規定每一步只能往左下或右下走,求出最大路徑和。遞迴解法 include include us...
《動態規劃》 ACM 動態規劃例題詳解
描述 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 圖1 圖1給出了乙個數字三角形。從三角形的頂部到底部有很多條不同的路徑。對於每條路徑,把路徑上面的數加起來可以得到乙個和,你的任務就是找到最大的和。注意 路徑上的每一步只能從乙個數走到下一層上和它最近的左邊的那個數或者右邊的那個數。輸...