多重揹包問題

2021-09-30 17:07:31 字數 1732 閱讀 6813

多重揹包的題目(杭電2191題):

《揹包九講》

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

基本演算法

這題目和完全揹包問題很類似。基本的方程只需將完全揹包問題的方程略微一改即可。因為對於第 i 種物品有 m i +1 種策略:取 0 件,取 1 件……取 m i 件。令 f[i,v] 表示前 i 種物品恰放入乙個容量為 v 的揹包的最大價值,則有狀態轉移方程:f[i , v] = max ,複雜度是 o(v σm i ) 。

同樣先考慮情景:dp[w][i]

1.當c[i]*d[i]>=w時,可以把第i類的東西看成是無限的,即是乙個完全揹包問題

2.當c[i]*d[i]<w時,可以把第i類的東西看成1個1個,即d[i]個01揹包問題,當d[i]數量太多時,明顯效率太低,因此可以把1個1個,看成1個,2個,4個…,2x個,d[i]-[2(x+1)-1]個(2^(x+2)-1>d[i])這樣對於1…d[i]的任意個數,都可由1,2,4,8…組成,即考慮了第i組,1,2,3…d[i]的每種情況,這樣求出的最優解也必定是最優解,同樣再對其進行壓縮,按各種的情景進行求解。

3、更高階的是樓天城的單調佇列法

#include#includeusing namespace std;

int n,m; //n為物品的種類數,m為揹包最大承載重量

int dp[1005]; // dp狀態陣列

int num[1005]; //物品的數量

int value[1005]; //物品的價值

int weight[1005];//物品的重量

void init() //輸入函式

int main()

cout<#includeusing namespace std;

int n,m; //n為物品的種類數,m為揹包最大承載重量

int dp[1005]; // dp狀態陣列

int num[1005]; //物品的數量

int value[1005]; //物品的價值

int weight[1005];//物品的重量

/*多重揹包問題的二進位制解法

*/void init() //輸入函式

void bag01(int heft,int worth) //01揹包

}void completebag(int heft,int worth) //完全揹包

}int main()

else //多個01揹包

}cout《本人開始對bag01(weight[i](num[i]-t+1),value[i](num[i]-t+1));這一條語句不甚理解,原來是因為t無法遍歷到t=d[i],故此需要新增這一條語句。

舉個例子,假設d[i]=6,乙個for迴圈執行了bag01(weight[i]*1,value[i]*1)和bage01(weight[i]2,value[i]2),此時t=4跳出迴圈,此時已經有3個此物品已經放入揹包了,所以我們補上了這一條語句bag01(weight[i](num[i]-t+1),value[i](num[i]-t+1));,而num[i]-t+1的值正好等於3,所以將最後的3的物品也加入了揹包,所以6個物品都加入了揹包之中,至於裝了幾個,則完全看bag01函式即揹包是否裝得下(這就是多重揹包了,即多個01揹包)。

多維多重揹包問題 多重揹包問題

悼念512汶川大 遇難同胞 珍惜現在,感恩生活 急!災區的食物依然短缺!為了挽救災區同胞的生命,心繫災區同胞的你準備自己採購一些糧食支援災區,現在假設你一共有資金n元,而市場有m種大公尺,每種大公尺都是袋裝產品,其 不等,並且只能整袋購買。請問 你用有限的資金最多能採購多少公斤糧食呢?後記 人生是乙...

揹包問題 多重揹包

有n種物品和乙個容量為w的揹包。第i種物品最多有n i 件可用,每件重量是w i 價值是v i 求解將哪些物品裝入揹包可使這些物品的重量總和不超過揹包容量,且價值總和最大。1.使用三重迴圈進行遞推 狀態轉移式為 dp i j max 關鍵 如下 void solve printf d n dp n ...

多重揹包問題

有n種物品和乙個容量為v的揹包。第i種物品最多有n i 件可用,每件費用是c i 價值是w i 求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。這題目和完全揹包問題很類似。基本的方程只需將完全揹包問題的方程略微一改即可,因為對於第i種物品有n i 1種策略 取0件,取1件...