在這我就廢話少說,直接貼上**供我們來比較一下啊。
**一:宣告乙個 大小為 dp[ c ]
的二維陣列,表示
面對於前i個物品,能獲得的最大容量(也可以看成從前往後推
),那麼我們可以很容易找出它的
狀態轉移方程
:dp[ c ] = max(dp[ c ],dp [j-w[ i ]]+v[ i])
(j>=w[ i ])
for(int i=1;i<=n;i++)
for(int j=c;j>=w[i];j--) ///c為總容量
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
printf("%d\n",dp[c]);
這裡j
是從c->w[i](從大到小),因為只有這樣我們才能夠保證再前i中,(我們先假設大j>小j)每次的
dp[大j]不會影響接下的dp[小j],
因為接下的小j無論它怎麼減,都不會與此次前面的大j,因為相等而搭上一絲絲的瓜葛。每一次的dp[j]都要保證是從前i個推來的。要是我們調換順序的話,我們可以想下,那按這種情況的話,
j是從w[i]->c(從小到大)後面的大j是不是比前面的小j大,那這樣的話,假如
此次前面的dp[小j]已經更新了,
那這樣就
很有可能會影響後面的dp[大j](
因後面的
大j減去w[i]時可能會和
此次前面
更新過的小j
相等而可能發生更新
,這樣就不滿足此次大j(後面)是從前i次推過來的了,因為更新的條件是:每次更新都是
不能被此次前面的更新的影響下進行的),
嗯,再接著完全揹包說說:
for(int i=1;i<=n;i++)
for(int j=w[i];j<=c;j++) ///c為總容量
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
printf("%d\n",dp[c]);
這裡j
是從w[i]->c(從小到大),啊,我猜你們聽了我上面說的可能大概或許有點懵,那我就
舉個特例
來解釋這個完全揹包的**吧,從這兩個**我們可以知道,只是
j的迴圈方向不同而已
,現在我們就假設i
就等於1,w=3,v=4,c=15,
現在我們只要小推以下就能明白為什麼要從小到大了,如果是
從大到小
,最後結果是
4,如果
從小到大
,結果就是20。
因為完全揹包的條件是:
每次更新都是
可以被此次前面的更新的影響下進行的。
0 1揹包與完全揹包
現有 n 件物品,乙個最大容量為 w 的揹包。第 i 件物品重量為 wi 價值為 vi 已知對於一件物品,你必須選擇取或不取,且每件物品只能被取一次 這就是 0 1 的含義 求放置哪幾件物品進揹包,使得揹包中物品價值最大 或是求最大價值是多少等衍生問題 設 ans n,w 為當揹包容重量為 w 有 ...
揹包問題 01揹包與完全揹包
一 介紹 揹包問題是最廣為人知的動態規劃問題,都是給定限定的揹包容量與物品,求所能裝下的最大價值 完全揹包 有n種物品,每種均有無限多,第i種物品額體積為v i 重量 價值 為w i 01揹包 有n種物品,每種只有乙個,第i種物品額體積為v i 重量 價值 為w i 在揹包問題中,我們把不同種的物品...
01揹包,完全揹包
動態規劃 動態規劃的核心是狀態以及狀態轉移方程。需要定義乙個 i,j 狀態以及該狀態的指標函式d i,j 01揹包 有n種物品,每種只有乙個,第i件物品的體積為vi質量為wi。選一些物品裝到體積為c的揹包中,使其體積不超過c的前提下重量最大。namevw abcd e 子問題定義 dp i j 表示...