http://acm.hdu.edu.cn/showproblem.php?pid=1171
这个问题首先由最大价值除以2,求出B理论可以达到的最大价值。
然后应用多重背包的方法求出B实际可以达到的最大价值,然后A的价值为总价值减去B。
#include <iostream>
using namespace std;
#define NI 105*50
#define NVALUE 1005*55*105
int sum[NVALUE],value[NI];
int max(int a,int b){
return a>=b?a:b;
}
int main(){
int n,v,m,count,k;
int total_v,volume,i,j;
while (scanf("%d",&n)!=EOF&&n>0){
count=1;
total_v=0;
while (n--){ //多重背包二进制思想处理输入
scanf("%d%d",&v,&m);
total_v+=v*m;
for (k=1;k<=m;k=k<<1){
value[count]=k*v;
m=m-k;
count++;
}
if (m>0){
value[count]=m*v;
count++;
}
}
volume=total_v/2;
count=count-1;
memset(sum,0,sizeof(sum));
for (i=1;i<=count;i++) //01背包的解决方案
for (j=volume;j>=value[i];j--)
sum[j]=max(sum[j],sum[j-value[i]]+value[i]);
printf("%d %d\n",total_v-sum[volume],sum[volume]);
}
return 0;
}