多重揹包模板

2021-08-05 20:12:28 字數 1270 閱讀 4471

有n種物品和乙個容量為v的揹包。第i種物品最多有num[i]件可用,每件費用是c[i],價值是w[i]。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。

多重揹包問題的思路跟完全揹包的思路非常類似,只是k的取值是有限制的,因為每件物品的數量是有限制的,狀態轉移方程為:

dp[i][v] = max

其中c[i]是物品的數量,和完全揹包的不同支出在於完全揹包可以取無數件,而多重揹包給定了最多能取的數量。這樣也是三個迴圈,分別是揹包容量,物品個數和物品種類。這樣如果數量比較多的情況,很明顯這個做法也會超時,所以我們也要想更優化的方法去完善。

轉化為01揹包問題

轉化為01揹包求解:把第i種物品換成n[i]件01揹包中的物品。考慮二進位制的思想,考慮把第i種物品換成若干件物品,使得原問題中第i種物品可取的每種策略——取0..n[i]件——均能等價於取若干件代換以後的物品。另外,取超過n[i]件的策略必不能出現。

方法是:將第i種物品分成若干件物品,其中每件物品有乙個係數,這件物品的費用和價值均是原來的費用和價值乘以這個係數。使這些係數分別為1,2,4,…,2^(k-1),n[i]-2^k+1,且k是滿足n[i]-2^k+1>0的最大整數。例如,如果n[i]為13,就將這種物品分成係數分別為1,2,4,6的四件物品。

分成的這幾件物品的係數和為n[i],表明不可能取多於n[i]件的第i種物品。另外這種方法也能保證對於0..n[i]間的每乙個整數,均可以用若干個係數的和表示,證明我也沒看過這裡就不貼上了,主要還是需要去理解**,**在下面給出。

#include 

#include

#include

#include

using

namespace

std;

const

int n=1e6+1100;

int v[n], w[n], num[n];

int dp[n];

int n,m;

//01揹包

void zeroonepack(int v, int w)

}//完全揹包

void completepack(int v, int w)

}//多重揹包

void multiplepack(int v, int w, int num)

else

//否則就將多重揹包轉化為01揹包

zeroonepack(num*v, num*w);

}}int main()

return

0;}

多重揹包模板

多重揹包模板 1.多重揹包 優化 例題 有n種物品,每種物品的數量為c1,c2.cn。從中任選若干件放在容量為w的揹包裡,每種物品的體積為w1,w2.wn wi為整數 與之相對應的價值為p1,p2.pn pi為整數 求揹包能夠容納的最大價值。input 第1行,2個整數,n和w中間用空格隔開。n為物...

模板 多重揹包

學習了二進位制優化,吼吼!寫個模板,雖然這種型別並不需要模板,但是寫乙個,備忘 模板 int dp n void onezeropack int v int n int w void completepack int v int n int w void multipliepack int v in...

多重揹包模板

hdu 2844 二進位制優化 includeusing namespace std define maxn 100500 define ll long long ll n,m ll num maxn v maxn w maxn ll dp maxn void zeroonepack ll w,ll...