1086 背包问题 V2
题目描述
有N种物品,每种物品的数量为C1,C2……Cn。从中任选若干件放在容量为W的背包里,每种物品的体积为W1,W2……Wn(Wi为整数),与之相对应的价值为P1,P2……Pn(Pi为整数)。求背包能够容纳的最大价值。
输入
第1行,2个整数,N和W中间用空格隔开。N为物品的种类,W为背包的容量。(1 <= N <= 100,1 <= W <= 50000)
第2 - N + 1行,每行3个整数,Wi,Pi和Ci分别是物品体积、价值和数量。(1 <= Wi, Pi <= 10000, 1 <= Ci <= 200)
输出
输出可以容纳的最大价值。
样例
Input示例
3 6
2 2 5
3 3 8
1 4 1
Output示例
9
题意
多重背包 二进制进行拆分化为01背包即可
AC代码
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <string>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <fstream>
#include <list>
#include <iomanip>
#include <numeric>
using namespace std;
#define ls st<<1
#define rs st<<1|1
#define fst first
#define snd second
#define MP make_pair
#define PB push_back
#define LL long long
#define PII pair<int,int>
#define VI vector<int>
#define CLR(a,b) memset(a, (b), sizeof(a))
#define ALL(x) x.begin(),x.end()
#define rep(i,s,e) for(int i=(s); i<=(e); i++)
#define tep(i,s,e) for(int i=(s); i>=(e); i--)
const int INF = 0x3f3f3f3f;
const int MAXN = 2e5+10;
const int mod = 1e9+7;
const double eps = 1e-8;
void fe() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt","w",stdout);
#endif
}
LL read()
{
LL x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return x*f;
}
int n, w;
int wi, pi, ci;
int c[MAXN], v[MAXN];
int dp[MAXN];
int main(int argc, char const *argv[])
{
cin >> n >> w;
int cnt = 1;
for(int i = 0; i < n; i++) {
cin >> wi >> pi >> ci;
int k = 1;
while(ci) {
if(ci >= k) {
c[cnt] = k*wi;
v[cnt++] = k*pi;
ci -= k;
k <<= 1;
} else {
c[cnt] = ci*wi;
v[cnt++] = ci*pi;
ci = 0;
}
}
}
for(int i = 0; i < cnt; i++) {
for(int j = w; j >= c[i]; j--) {
dp[j] = max(dp[j], dp[j-c[i]]+v[i]);
}
}
cout << dp[w] << endl;
return 0;
}