混合揹包問題(三種揹包問題的總結)

2021-10-02 10:41:45 字數 1467 閱讀 7139

有 n 種物品和乙個容量是 v 的揹包。

物品一共有三類:

每種體積是 vi,價值是 wi。

求解將哪些物品裝入揹包,可使物品體積總和不超過揹包容量,且價值總和最大。

輸出最大價值。

輸入格式

第一行兩個整數,n,v,用空格隔開,分別表示物品種數和揹包容積。

接下來有 n 行,每行三個整數 vi,wi,si用空格隔開,分別表示第 i 種物品的體積、價值和數量。

輸出格式

輸出乙個整數,表示最大價值。

資料範圍

0輸入樣例

4 5

1 2 -1

2 4 1

3 4 0

4 5 2

輸出樣例:

8
混合揹包就是按照把01揹包(每個物品只能用1次)完全揹包(每個物品可以用無限次)多重揹包(每個物品最多只能用 si 次)混合起來,所以對於不同種類的物品,分類處理即可。

對於01揹包和完全揹包直接存起來即可,對於多重揹包採用二進位制拆分的方法,將份數s拆成多個位權,每個位權作為數量,分別用v和w乘該數量作為乙個單位物品(相當於01揹包的物品,只有選和不選兩種狀態),最後注意:

在狀態轉移時,內層迴圈的體積:01揹包是從大到小逆序遍歷,而完全揹包是從小到大順序遍歷

因為01揹包要求每件物品只能放一次,若從小到大遍歷,根據狀態轉移方程可以看出,[j-v[i]]中的v[i]比當前體積j小,在遍歷j之前就改動過v[i](即放過體積為v[i]的物品了,此時j>v[i]可能會又放了一次v[i]),導致不是由i-1狀態轉移過來的,而是從當前i狀態轉移過來的,從而發生了錯誤,就會出現某件物品放了超過一次的情況,會發生錯誤,採用逆序可以保證每件物品只放一次;而完全揹包每件物品可以放無限個,所以從小到大逐個列舉即可(即:只要揹包容量足夠大,當前物品能放幾次就放幾次);

證明過程參考:

#include #define int long long

using namespace std;

int n,m,f[1010];

struct thing

;vectorthings;

signed main()

); }

else if(s==0));

}else);

}if(s>0));}}

}for(int i=0;i=things[i].v;j--)

}else}}

cout

}

混合三種揹包問題

問題 如果將01揹包 完全揹包 多重揹包混合起來。也就是說,有的物品只可以取一次 01揹包 有的物品可以取無限次 完全揹包 有的物品可以取的次數有乙個上限 多重揹包 應該怎麼求解呢?01揹包與完全揹包的混合 考慮到在01揹包和完全揹包中最後給出的偽 只有一處不同,故如果只有兩類物品 一類物品只能取一...

混合三種揹包問題

問題 如果將01揹包 完全揹包 多重揹包混合起來。也就是說,有的物品只可以取一次 01揹包 有的物品可以取無限次 完全揹包 有的物品可以取的次數有乙個上限 多重揹包 應該怎麼求解呢?01揹包與完全揹包的混合 考慮到在01揹包和完全揹包中最後給出的偽 只有一處不同,故如果只有兩類物品 一類物品只能取一...

混合三種揹包問題

問題 如果將 01揹包問題 完全揹包問題 多重揹包問題混合起來。也就是說,有的物品只可以取一次 01揹包 有的物品可以取無限次 完全揹包 有的物品可以取的次數有乙個上限 多重揹包 應該怎麼求解呢?考慮到在 01揹包問題 和 完全揹包問題 中給出的偽 只有一處不同,故如果只有兩類物品 一類物品只能取一...