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

2022-06-26 09:42:07 字數 2593 閱讀 9309

1

for (int i=0; i)

2for (int j=w; j>=size[i]; j--)

3 f[j] = max(f[j], f[j-size[i]]+value[i]);

1

for (int i=0; i)

2for (int j=size[i]; j<=w; j++)

3 f[j] = max(f[j], f[j-size[i]]+value[i]);

f[w] 即為所求  

初始化分兩種情況:

1、如果揹包要求正好裝滿則初始化 f[0] = 0, f[1~w] = -inf;  

2、如果不需要正好裝滿 f[0~v] = 0;  

舉例:01揹包

v=10,n=3,c=, w=

(1)揹包不一定裝滿

計算順序是:從右往左,自上而下:因為每個物品只能放一次,前面的體積小的會影響體積大的

(2)揹包剛好裝滿    

計算順序是:從右往左,自上而下。注意初始值,其中-inf表示負無窮

完全揹包:

v=10,n=3,c=, w=

(1)揹包不一定裝滿

計算順序是:從左往右,自上而下:  每個物品可以放多次,前面的會影響後面的

(2)揹包剛好裝滿

計算順序是:從左往右,自上而下。注意初始值,其中-inf表示負無窮

多重揹包:  

多重揹包問題要求很簡單,就是每件物品給出確定的件數,求可得到的最大價值  

多重揹包轉換成 01 揹包問題就是多了個初始化,把它的件數c 用二進位制分解成若干個件數的集合,這裡面數字可以組合成任意小於等於c的件數,而且不會重複,之所以叫二進位制分解,是因為這樣分解可以用數字的二進位制形式來解釋  

比如:7的二進位制 7 = 111 它可以分解成 001 010 100 這三個數可以組合成任意小於等於7 的數,而且每種組合都會得到不同的數  

15 = 1111 可分解成 0001  0010  0100  1000 四個數字  

如果13 = 1101 則分解為 0001 0010 0100 0110 前三個數字可以組合成  7以內任意乙個數,即1、2、4可以組合為1——7內所有的數,加上 0110 = 6 可以組合成任意乙個大於6 小於等於13的數,比如12,可以讓前面貢獻6且後面也貢獻6就行了。雖然有重複但總是能把 13 以內所有的數都考慮到了,基於這種思想去把多件物品轉換為,多種一件物品,就可用01 揹包求解了。  

看**:  

int n;  //

輸入有多少種物品

int c; //

每種物品有多少件

int v; //

每種物品的價值

int s; //

每種物品的尺寸

int count = 0; //

分解後可得到多少種物品

int value[max]; //

用來儲存分解後的物品價值

int size[max]; //

用來儲存分解後物品體積

scanf("%d

", &n); //

先輸入有多少種物品,接下來對每種物品進行分解

while (n--) //

接下來輸入n中這個物品

if (c > 0

)

}

定理:乙個正整數n可以被分解成1,2,4,…,2^(k-1),n-2^k+1(k是滿足n-2^k+1>0的最大整數)的形式,且1~n之內的所有整數均可以唯一表示成1,2,4,…,2^(k-1),n-2^k+1中某幾個數的和的形式。

證明如下:

(1) 數列1,2,4,…,2^(k-1),n-2^k+1中所有元素的和為n,所以若干元素的和的範圍為:[1, n];

(2)如果正整數t<= 2^k – 1,則t一定能用1,2,4,…,2^(k-1)中某幾個數的和表示,這個很容易證明:我們把t的二進位制表示寫出來,很明顯,t可以表示成n=a0*2^0+a1*2^1+…+ak*2^(k-1),其中ak=0或者1,表示t的第ak位二進位制數為0或者1.

(3)如果t>=2^k,設s=n-2^k+1,則t-s<=2^k-1,因而t-s可以表示成1,2,4,…,2^(k-1)中某幾個數的和的形式,進而t可以表示成1,2,4,…,2^(k-1),s中某幾個數的和(加數中一定含有s)的形式。

(證畢!)

現在用count 代替 n 就和01 揹包問題完全一樣了  

杭電2191題解:此為多重揹包用01和完全揹包:

#include#include

int dp[102

];int p[102],h[102],c[102

];int

n,m;

void comback(int v,int w)//

經費,重量。完全揹包;

void oneback(int v,int w)//

經費,重量;01揹包;

intmain()

oneback(p[i]*c[i],h[i]*c[i]);}}

printf(

"%d\n

",dp[n]);

}return0;

}

揹包問題(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元的鈔票 記住,只有一張...