51nod 多重背包 [二进制优化]

问题描述

一个背包,承量有限为W,有n种物体,第i种物体,价值Vi,占用重量为 Wi,且有Ci件,选择物品若干放入背包,使得总重量不超过背包的承重。总价值最大?

思路:

把C物品分开来对待,就成了01背包问题。但是如果C的数量特别大的时候这样做的效率显然不够。可以用二进制优化下。

例如一个物品有10个,可以把10拆成1, 2 ,4, 3,这几个数的组合可以是10内的任何数,显然和一个一个的对待等价。

#include "bits/stdc++.h"
using namespace std;
const int maxn = 50000 + 10;
int sz[maxn], val[maxn];
int dp[maxn];
int main(int argc, char const *argv[]) {
int N, W;
scanf("%d%d", &N, &W);
int cnt = 0;
int w, p, c;
for (int i = 0; i < N; i++) {
scanf("%d%d%d", &w, &p, &c);
for (int k=1; k<=c; k<<=1) {
val[cnt] = k*p;
sz[cnt++] = k*w;
c -= k;
}
if (c > 0) val[cnt] = c*p, sz[cnt++] = c*w;
}
for (int i = 0; i < cnt; i++) {
for (int j = W; j >= sz[i]; j--) {
dp[j] = max(dp[j], dp[j - sz[i]]+val[i]);
}
}
printf("%d ", dp[W]);
return 0;
}
原文地址:https://www.cnblogs.com/cniwoq/p/7340243.html