揹包問題是動態規劃裡面很重要的一部分,徹底理解各種揹包問題,對動態規劃的後續學習有很大的幫助.
更全的揹包問題,可參看《揹包九講》.
學會了0-1揹包後,多重揹包、完全揹包就比較容易理解.
一.什麼是「完全揹包」?
有這樣乙個問題:
在你面前放著n種寶石,每種寶石重量為wi,價值為vi,數量無限;你有乙個最多可以放m重量的揹包。現在你想在不超重的情況下,是你帶走的寶石價值最大,問最大價值是多少?
二.如何做?
我們來看一道題,鏈結.
題目意思:你有乙個空間為w的揹包,在你前面放著n種石頭,每種石頭的價值為vi,體積為wi,數量無限.問:將揹包裝滿,至少需要多少價值的石頭?
我們從第一種物品開始取,for(i=1 to n).
設:dp[j]表示前i種物品,取得重量為j的石頭時,需要的石頭的最小價值.初始時dp[0]=0,其他為無窮大.
那麼:dp[j]=min(dp[j],dp[j-w[i]]+v[i]).
即:for(inti=
0; i
<=
m; ++
i)dp[i
]=inf;dp[
0]=0;
for(inti=
0; i
注意:這兒的內迴圈是順序!而0-1揹包的內迴圈是逆序.
為什麼?
我們在做0-1揹包,計算dp[i][j]的時候,需要用到前面的值,而這個值是前i-1個物品的值(相當於更新前i-1個物品的值).
而在做完全揹包,計算dp[j]時,我們需要更新的是當前狀態,也就是前i個物品的值.(也就是說:用前i-1個的值和當前值比較,更新當前值).
**:(跟著**計算一遍即可理解)
/** this code is made by crazyacking
* verdict: accepted
* submission date: 2013-10-29-10.19
* time: 0ms
* memory: 137kb
*/#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define max(a,b) (a>b?a:b)
using
namespace
std;
typedef
long
long(ll);
typedef
unsigned
long
long(ull);
const
double
eps(1e-8);
const
intmaxn
=510;
const
intmaxm
=10010;
const
intinf
=(int)1e9+7;
intdp
[maxm
];intw[
maxn],v
[maxn
];int
main()
for(inti=
0;i<=
m;++
i)dp[i
]=inf;dp[
0]=0;
for(inti=
0;iif(dp[m
]==inf)
cout
<<
"this is impossible."
<<
endl;
else
cout
<<
"the minimum amount of money in the piggy-bank is "
<< "."<< endl; }return0;} /**/ 背景 有n種物品和乙個容量為v的揹包,每種物品都有無限件可用。第i種物品的費用是c i 價值是w i 求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。我們注意看紅字部分,完全揹包與01揹包的不同之處在於每件物品有無限個,故而對於完全揹包策略要從 選與不選轉變為 選幾件 0... 揹包之01揹包 完全揹包 多重揹包詳解 ps 大家覺得寫得還過得去,就幫我把部落格頂一下,謝謝。首先說下動態規劃,動態規劃這東西就和遞迴一樣,只能找區域性關係,若想全部列出來,是很難的,比如漢諾塔。你可以說先把除最後一層的其他所有層都移動到2,再把最後一層移動到3,最後再把其餘的從2移動到3,這是乙... 首先說下動態規劃,動態規劃這東西就和遞迴一樣,只能找區域性關係,若想全部列出來,是很難的,比如漢諾塔。你可以說先把除最後一層的其他所有層都移動到2,再把最後一層移動到3,最後再把其餘的從2移動到3,這是乙個直觀的關係,但是想列舉出來是很難的,也許當層數n 3時還可以模擬下,再大一些就不可能了,所以,...完全揹包詳解
01揹包,完全揹包,多重揹包詳解
揹包之01揹包 完全揹包 多重揹包詳解