二進位制優化多重揹包

2022-04-05 22:09:16 字數 1520 閱讀 8657

優化多重揹包的方式中兩種常用的是單調佇列和二進位制優化,今天主要學習了一下二進位制優化(徵集各方資料)。

先說下 01 揹包,有n 種不同的物品,每個物品有兩個屬性 :$ size $ 體積,$ value $ 價值,現在給乙個容量為 $ w $ 的揹包,問 最多可帶走多少價值的物品。

int f[w+1];   //f[x] 表示揹包容量為x 時的最大價值  

for (int i=0; i=size[i]; j++)

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

如果物品不計件數,就是每個物品不只一件的話,稍微改下即可

for (int i=0; i初始化分兩種情況

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

2、如果不需要正好裝滿 $ f[0->w] = 0; $

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

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

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

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

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

看**的話:

int n; //輸入有多少種物品

int c; //每種物品有多少件

int v; //每種物品的價值

int s; //每種物品的尺寸

int count = 0; //分解後可得到多少種物品

int value[max]; //用來儲存分解後的物品價值

int size[max]; //用來儲存分解後物品體積

scanf("%d", &n); //先輸入有多少種物品,接下來對每種物品進行分解

while (n--)

if (c > 0)

}

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

下面證明一下為什麼有重複沒有影響的正確性:

不正確可能產生的原因就是將重複的多加一次,比如 7+7=14 就可能造成錯誤,但是分析一下其實是不可能出現的,因為假如第乙個 7 是由 0001+0010+0100 得到的,那麼第二個 7 就需要用到 0110+0001,但 0001 只能出現一次嘛,所以不會形成這種錯誤的,其它的可能錯誤操作也能由這種解釋進行否定,從而驗證了正確性。

多重揹包二進位制優化

多重揹包二進位制優化 將價值數量相同的物品分成1,2,4,8.因為100以內任何數都可以由幾個2的n次方數組成。所以,有遍歷沒乙個數變為遍歷每乙個2的n次方數。例題 有n種物品,每種物品的數量為c1,c2.cn。從中任選若干件放在容量為w的揹包裡,每種物品的體積為w1,w2.wn wi為整數 與之相...

多重揹包(二進位制優化)

馬上就要輕院校賽了,沒時間了,下面是網上找的多重揹包,感覺很好 void zeroonepack int cost,int weight,int n void completepack int cost,int weight,int n void multipack int c,int w,int ...

多重揹包二進位制優化

時間長不寫 感覺變菜了。整體優化思路和快速冪很相近 如果第i個物品有num i 個,花費是 c i 價值是 v i 那麼我們可以把它拆分成數個物品。比如某個物品數量是14 花費是cost 價值是value 1 2 4 7 就可以把14個相同物品看成 4 個不同的物品,物品 數量花費 價值第乙個 11...