题意:分物品,使得两份的价值差最小。
方法:相当于求容量为sum/2的最大价值,所以,所需费用=当前物品价值
#define N 55
int v[N],m[N];
int dp[50*50*100+100];
int V;//容量
void zeroone(int cost,int val){//费用,价值
int i;
for(i=V;i>=cost;i--){
if(dp[i]<dp[i-cost]+val){
dp[i] = dp[i-cost]+val;
}
}
}
void complete(int cost,int val){//费用,价值
int i;
for(i=cost;i<=V;i++){
if(dp[i]<dp[i-cost]+val){
dp[i] = dp[i-cost]+val;
}
}
}
void multi(int cost,int val,int cnt){//费用,价值,数量
if(cost*cnt>=V){
complete(cost,val);
return ;
}
int k = 1;
while(k<cnt){
zeroone(k*cost,k*val);
cnt -= k;
k *= 2;
}
zeroone(cnt*cost,cnt*val);
}
int main(){FRE;
int n;
while(scanf("%d",&n) && n>=0){
int i,j,k;int sum = 0;
for(i=0;i<n;i++){
scanf("%d%d",&v[i],&m[i]);
sum+=v[i]*m[i];
}
for(i=0;i<=sum/2;i++){
dp[i] = 0;
}
V = sum/2;//相当于求容量为sum/2的最大价值
for(i=0;i<n;i++){
multi(v[i],v[i],m[i]);//注意所需费用等于当前物品价值
}
i = sum/2;
printf("%d %d\n",sum-dp[V],dp[V]);
}
return 0;
}