揹包問題 01揹包與完全揹包

2021-08-17 03:52:10 字數 1536 閱讀 3312

一、介紹

揹包問題是最廣為人知的動態規劃問題,都是給定限定的揹包容量與物品,求所能裝下的最大價值:

完全揹包:

有n種物品,每種均有無限多,第i種物品額體積為v[i],重量(價值)為w[i]。

01揹包:

有n種物品,每種只有乙個,第i種物品額體積為v[i],重量(價值)為w[i]。

在揹包問題中,我們把不同種的物品設為不同的階段,即有n各階段。

二、狀態定義

定義狀態d[i][j],表示把前i種物品裝到容量為j的揹包中的最大價值。

每次操作的物件是單個物品,那麼對於物品有裝入或者不裝兩種選擇。

注:示例輸入:

n=3,v=9,v1=2,w1=2,v2=2,w2=2,v3=5,w3=6

三、完全揹包

之所以叫完全揹包,是因為每種物品均有無限多。

狀態轉移:

d[i][j]=max

max種第一項表示不裝第i種,跳過此種;第二項表示裝入此種,判定還留在此種。

普通實現:

#include using namespace std;

int n,v,v[50],w[50],d[50][500];

int main()

cout《注:在迴圈中首先要先進行:d[i][j]=d[i-1][j]而不直接進行max操作,是因為若j執行程式可得結果為10,即選擇了兩個第一種物品與乙個第三種物品。

滾動陣列實現:

#include using namespace std;

int n,v,v[50],w[50],d[50];

int main()

不管放入或不放入都跳到下一種的判定。

普通實現:

#include using namespace std;

int n,v,v[50],w[50],d[50][500];

int main()

cout《執行結果為9,即放入了第二種與第三種

滾動陣列:

#include using namespace std;

int n,v,v[50],w[50],d[50];

int main()

{ cin>>n>>v;

for(int i=1;i<=n;i++)

cin>>v[i]>>w[i];

for(int i=1;i<=n;i++)

for(int j=v;j>=v[i];j--)

d[j]=max(d[j],d[j-v[i]]+w[i]);

cout《五、兩種揹包滾動陣列實現對比

可以看01與完全揹包在滾動陣列中,只在內層迴圈次序不同,這是因為它們上乙個狀態不同導致,應回溯到其本質的狀態轉移方程。

對於存在兩層迴圈的陣列d[i][j],若i遞增,那麼對於其滾動陣列d[j],原陣列與滾動陣列的對應關係為:

d[j]->d[i-1][j]

對於正數k:

j遞增:d[j-k]->d[i][j-k];d[j+k]->d[i-1][j+k]

j遞減:d[j-k]->d[i-1][j-k];d[j+k]->d[i][j+k]

揹包問題(0 1揹包 完全揹包)

0 1揹包 有n件物品和乙個容量為v的揹包。第i件物品的費用是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。重要的點在於 每種物品僅有一件,可以選擇放 不放子問題 f i v 表示前i件物品恰好放入乙個 容量為v 的揹包可以獲得的最大價值。狀態轉移方程 遞推式 f i v max 考...

揹包問題 01揹包 完全揹包 多重揹包

01揹包和完全揹包的區別 01揹包的侷限在於每樣物品只有一種,每個物品都有乙個屬於自己的價值和重量,在給定的物品中選出揹包所能容納的最大重量,要求是價值最大 完全揹包與01揹包的不同在於完全揹包不限制每樣物品的個數,物品的價值和質量都與01揹包一樣,也同樣是求在給定大小的容量中,找出最大價值的選擇 ...

揹包問題(01揹包,完全揹包,多重揹包)

揹包問題 01揹包,完全揹包,多重揹包 近日為以下瑣事煩身 差不多要向學院提交專案申請了,本來是想做個多模式的im系統的,可是跟往屆通過審核的專案比起來,缺乏創新和研究價值,所以在文件上要多做手腳,花點心思。揹包問題,經典有揹包九講。不死族的巫妖王發工資拉,死亡騎士拿到一張n元的鈔票 記住,只有一張...