005多重揹包問題||
題目描述:
有 N種物品和一個容量是 V 的揹包。
第 i種物品最多有 si 件,每件體積是 vi,價值是 wi。
求解將哪些物品裝入揹包,可使物品體積總和不超過揹包容量,且價值總和最大。 輸出最大價值。
輸入格式:
第一行兩個整數,N,V用空格隔開,分別表示物品種數和揹包容積。
接下來有 N 行,每行三個整數 vi,wi,si用空格隔開,分別表示第 i種物品的體積、價值和數量。
輸出格式:
輸出一個整數,表示最大價值。
資料範圍:
0<N≤10000 0<V≤20000 0<vi,wi,si≤20000
提示: 本題考查多重揹包的二進位制優化方法。輸入樣例:
4 5 1 2 3 2 4 1 3 4 3 4 5 2
輸出樣例:
10
這個題和多重揹包問題|中的題目描述是完全一樣的,不同的是資料範圍變大了,顯然我們要在原來的做法上做優化。
在解決這個問題之前,我們先來思考一下這個問題,如何把一個數s,拆成用最少的數表示呢?
解決辦法是:數s,s-1-2-4-8-…一直減到為負數為止,把這個數和前面的2的次冪數拿過來,這些數的組合可以表示0~s以內的任意數
同樣這個揹包問題,我們可以把物品拆成2的次冪份
#include<cstring>
#include<algorithm>
#include<vector>
#include<cstdio>
using namespace std;
int dp[2010];
//因為不知道最後選出了多少物品,所以定義一個結構體和一個vector容器
struct Good
{
int v,w;
};
int main()
{
vector<Good> goods;
int N,V;
cin>>N>>V;
int v,w,s;
int i,j,k;
for(i=0;i<N;i++){
cin>>v>>w>>s;
for(k=1;k<=s;k*=2){//拆成0-1揹包問題
s-=k;
goods.push_back({v*k,w*k});
}
if(s>0) goods.push_back({v*s,w*s});
}
//這裡就可以用0-1揹包問題了
for(auto good: goods){//auto遍歷vector容器,good就相當於goods[i]
for(int j=V;j>=good.v;j--){
dp[j] = max(dp[j],dp[j-good.v]+good.w);
}
}
cout<<dp[V];
return 0;
}
相關文章
- 深入剖析多重揹包問題(上篇)
- 深入剖析多重揹包問題(下篇)
- 01揹包、完全揹包、多重揹包詳解
- 多重揹包問題的單調佇列優化佇列優化
- 揹包問題(01揹包與完全揹包)
- 揹包問題
- hdu3591The trouble of Xiaoqian 多重揹包+全然揹包
- 01揹包問題
- 01 揹包問題
- javascript演算法基礎之01揹包,完全揹包,多重揹包實現JavaScript演算法
- 01揹包和完全揹包問題解法模板
- HDU - 2191 珍惜現在,感恩生活(多重揹包板題)
- 揹包九講問題
- 經典揹包問題
- 揹包問題大合集
- 部分揹包問題(挖
- 【BZOJ 5003】與鏈 (多重揹包 dp)
- 從【零錢兌換】問題看01揹包和完全揹包問題
- 揹包問題例題總結
- 【leetcode】揹包問題彙總LeetCode
- 2. 01揹包問題
- 揹包問題解題方法總結
- JavaScript中揹包問題(面試題)JavaScript面試題
- 51nod 1597 有限揹包計數問題 (揹包 分塊)
- chapter12-2-揹包問題APT
- 關於各種揹包問題
- 【動態規劃】揹包問題動態規劃
- 01揹包問題的解決
- 二維費用揹包問題
- 揹包問題----動態規劃動態規劃
- leetcode題解(0-1揹包問題)LeetCode
- 揹包問題的一道經典問題
- HDU Piggy-Bank(完全揹包問題)
- 整數0-1揹包問題
- 動態規劃 01揹包問題動態規劃
- 【動態規劃】01揹包問題動態規劃
- 動態規劃--01揹包問題動態規劃
- 動態規劃篇——揹包問題動態規劃