多重揹包的二進位制分解思想

2021-06-22 06:47:05 字數 2885 閱讀 3409

在揹包九講裡面將多重揹包轉化為01揹包,並且進行時間優化,有利用到乙個二進位制分解的思想。

下面是在網上搜尋之後得到的乙個關於二進位制分解思想的講解和實現

多重揹包二進位制分解思想講解

/**  

在這之前,我空間好像轉過乙個揹包九講,現在我就只對  

01揹包和多重揹包有點印象了  

先說下 01 揹包,有n 種不同的物品,每個物品有兩個屬性  

size 體積,value 價值,現在給乙個容量為 w 的揹包,問  

最多可帶走多少價值的物品。  

intf[w+1];   

//f[x] 表示揹包容量為x 時的最大價值

for(

inti=0; i

for(

intj=w; j>=size[i]; j++)  

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

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

for(

inti=0; i

for(

intj=size[i]; j<=w; j++)  

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 揹包問題就是多了個初始化,把它的件數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 揹包求解了。  

看**:  

intn;  

//輸入有多少種物品

intc;  

//每種物品有多少件

intv;  

//每種物品的價值

ints;  

//每種物品的尺寸

intcount = 0; 

//分解後可得到多少種物品

intvalue[max]; 

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

intsize[max];  

//用來儲存分解後物品體積

scanf("%d"

, &n);    

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

while

(n--)   

if(c > 0)   

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

下面是利用上面的講解,對

hdoj 2191

進行解答,**如下:

#include 

using

namespace

std;  

intmain()  

if(c[i] > 0)  

}  //經過上面對每一種物品的分解,

//現在value存的就是分解後的物品價值

//size存的就是分解後的物品尺寸

//count就相當於原來的n

//下面就直接用01揹包演算法來解

memset(dp,0,sizeof

(dp));  

for(i=0;i

for(j=limit;j>=size[i];j--)  

if(dp[j] < dp[j-size[i]] + value[i])  

dp[j]=dp[j-size[i]]+value[i];  

cout<}  

return

0;  

}  

在揹包九講裡面,他的實現方法和這個是不一樣的,他是利用01揹包和完全揹包來配合實現的,下面是那個版本的實現

/*hdoj 2191

多重揹包用二進位制轉化的思想,進行優化

*/#include 

using

namespace

std;  

intweight[110],value[110],num[110];  

intf[1100];  

intlimit;  

inline

void

zeroonepack(

intw,

intv)  

}  inline

void

completepack(

intw,

intv)  

}  inline

void

multiplepack(

intw,

intv,

intamount)  

for(int

k=1;k

zeroonepack(amount*w,amount*v);  

}  int

main()  

return

0;  

}  

多重揹包二進位制優化

多重揹包二進位制優化 將價值數量相同的物品分成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...