题目:https://cn.vjudge.net/contest/180638#problem/B
有N种物品,每种物品的数量为C1,C2......Cn。从中任选若干件放在容量为W的背包里,每种物品的体积为W1,W2......Wn(Wi为整数),与之相对应的价值为P1,P2......Pn(Pi为整数)。求背包能够容纳的最大价值。
思路:利用二分法优化多重背包,将多重背包转化成01背包。
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
#define maxn 50000+5
int dp[maxn],v[105],cost[105],c1[105];
int main()
{
int n, w,i,j,num;
while (~scanf("%d%d",&n,&w))
{
memset(dp, 0, sizeof(dp));
num = 0;
for (i = 1; i <= n; i++)
scanf("%d%d%d", &cost[i], &v[i], &c1[i]);
for (i = 1; i <= n; i++)
{
for (int k = 1; k <= c1[i]; k <<= 1)
{
for (j = w; j >= k*cost[i]; j--)
dp[j] = max(dp[j], dp[j - k*cost[i]] + k*v[i]);
c1[i] -= k;
}
int k = c1[i];
if (k == 0)
continue;
for (j = w; j >= k*cost[i]; j--)
dp[j] = max(dp[j], dp[j - k*cost[i]] + k*v[i]);
}
cout << dp[w] << endl;
}
return 0;
}