题目:hdu1171
题意:把一个多重背包尽可能地分成相等的两份。
解答:背包的总乘重为所有重量的一半,然后尽可能地接近这个总乘重就好。
<pre name="code" class="cpp">//多重背包
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 300000;
int dp[MAXN];
int N,W;
int value[55],num[55];
void zero_one_bag(int weight,int value)
{
for(int i = W;i >= weight;i--)
dp[i] = max(dp[i],dp[i - weight]+value);
return;
}
void certain_num_bag(int weight,int value,int num)
{
int k = 1;
while(k < num)
{
zero_one_bag(k*weight,k*value);
num -= k;
k <<= 1;
}
zero_one_bag(num*weight,num*value);
return;
}
int main()
{
while(~scanf("%d",&N))
{
if(N < 0)
break;
memset(dp,0,sizeof(dp));
int sum = 0;
for(int i = 1;i <= N;i++)
{
scanf("%d%d",&value[i],&num[i]);
sum += value[i] * num[i];
}
W = sum / 2;
for(int i = 1;i <= N;i++)
certain_num_bag(value[i],value[i],num[i]);
int A = max(dp[W],sum - dp[W]);
int B = sum - A;
printf("%d %d\n",A,B);
}
return 0;
}