五、0/1揹包演算法的優化:
給定一組物品,給出每種物品的價值和重量,每種物品足夠多,在限定重量內,如何選擇,才能使物品總價值最高
設 f(
x)表示
重量不超
過x千克
的最大價
值,則:
設f(x)表示重量不超過x千克的最大價值,則:
設f(x)表
示重量不
超過x千
克的最大
價值,則:f(
x)=m
ax
f(x) = max\
f(x)=m
ax( x≥
weig
ht[i
],1≤
i≤n)
(x \geq weight[i],1 \leq i \leq n)
(x≥wei
ght[
i],1
≤i≤n
)
// tsworld
#include
#include
#include
#include
#include
#include
#include
using
namespace std;
const
long
long maxx =
1000
;int
main()
,value[maxx]=;
int f[maxx]=;
cin>>n>>m;
for(
int i =
1;i <= n;i++
) cin>>weight[i]
>>value[i]
;for
(int i =
1;i <= m;i++)}
} cout<
}
4.1 思路分析:
可以用乙個陣列f[m
]f[m]
f[m]
來解決,陣列下標表示包的最大承重,f[m
]f[m]
f[m]
數值表示該承重下放的最大價值。可以代替wei
ght[
n]
weight[n]
weight
[n]和val
ue[n
]value[n]
value[
n]陣列,時間複雜度未優化。
動態轉移方程:
f (x
)=ma
x(f(
x−we
ight
)+va
lue,
f(x)
)f(x) = max(f(x - weight) + value,f(x))
f(x)=m
ax(f
(x−w
eigh
t)+v
alue
,f(x
))顯然只要m足夠大,就可以放無限個該物品
4.2 **:
// tsworld
#include
#include
#include
#include
#include
#include
#include
using
namespace std;
const
long
long maxx =
1000
;int
main()
; cin>>n>>m;
for(
int i =
1;i <= n;i++
) cout<
}
5.1 思路分析:
搜尋方向從後向前,每次計算都會用到小於當前下標的資料,所以即使後邊的下標放入該物品,前面的下標並沒有放置,因此計算出來的資料每個物品最多只能放乙個,也就是所謂的0/1揹包問題。顯然,該**與前面**幾乎完全一致,只是乙個是從前向後計算,乙個是從後向前計算,但是無論是時間複雜度,空間複雜度,程式複雜度和記憶複雜度均優於最初演算法。
5.2 **:
// tsworld
#include
#include
#include
#include
#include
#include
#include
using
namespace std;
const
long
long maxx =
1000
;int
main()
; cin>>n>>m;
for(
int i =
1;i <= n;i++
) cout<
}
動態規劃揹包問題 完全揹包
問題描述 有n種物品,每種均有無窮多個。第i個物品的體積為vi,重量為wi。選一些物品裝到容量為c的揹包中,使得揹包內物品在總體積不超過c的前提下重量盡量大。問題分析 開乙個陣列f i j 表示前i種物品中選取若干件物品放入剩餘空間為j的揹包中所能得到的最大重量。每種物品無窮個,所以還要有乙個k遍歷...
動態規劃 揹包問題 完全揹包
有n種物品和乙個容量為v的揹包,每種物品都有無限件可用。第i種物品的費用是w i 價值是v i 求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。貪心 y or n 因為每件物品都可以選取任意件,你也許會想到貪心演算法 選取價值最高的就好了 看上去沒什麼毛病,但是有乙個問題...
動態規劃揹包問題 完全揹包
問題背景描述 你有乙個容量為v的揹包,現在有n種物品供你選擇,每件物品可以選擇無數次,每種物品所佔的空間為c i 價值為v i 現在讓你作出最佳方案,使揹包中的總價值最大。有了之前01揹包的基礎,我們很快就能寫出完全揹包的狀態轉移方程 f i j max 但是這樣的時間複雜度就很大了o v v c ...