用多重背包来解的
据说可以用母函数
可是,我不会 = =
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <iomanip>
#include <cstring>
#include <iostream>
#include <algorithm>
#define BUG puts("HERE!")
using namespace std;
const int MAX = 5e3;
const int MAXDP = 1e6;
const int INF = 0x7fffff;
int dp[MAXDP], W, w[MAX];
int v[MAX], num[MAX];
void zop(int v, int w){
for (int i = W; i >= w; --i){
dp[i] = max(dp[i], dp[i - w] + v);
}
}
void cp(int v, int w){
for (int i = w; i <= W; ++i){
dp[i] = max(dp[i], dp[i - w] + v);
}
}
void mp(int v, int w, int a){
if(w * a >= W){
cp(v, w);
return;
}
for (int i = 1; i < a; a -= i, i <<= 1){
zop(i * v, i * w);
}
zop(a * v, a * w);
}
int main(int argc, char const *argv[]){
#ifndef ONLINE_JUDGE
freopen("in.in", "r", stdin);
// freopen("out.out", "w", stdout);
#endif
int n, sum;
while (~scanf("%d", &n) && n >= 0){
sum = 0;
memset(dp, 0, sizeof(dp));
for (int i = 0; i < n; ++i){
scanf("%d%d", v + i, num + i);
w[i] = v[i];
sum += v[i] * num[i];
}
W = sum / 2;
for (int i = 0; i < n; ++i){
mp(v[i], w[i], num[i]);
}
printf("%d %d\n", sum - dp[W], dp[W]);
}
return 0;
}