题意:给一个数n,接下来n行,每行对应一个设备的两个值,第一个为设备的价值,第二个为该设备的数量。如何把所有设备一分为二,求两部分的价值总和尽量接近。
#include <cstdio>
#include <cstring>
int W[59], M[59];
int F[295000];
#define _max(a, b) ((a) > (b) ? (a) : (b))
int main()
{
//freopen("1.txt", "r", stdin);
//freopen("2.txt", "w", stdout);
int n, i, s, ave;
while (scanf("%d", &n) != EOF && n > 0)
{
for (s = i = 0; i < n; ++i)
scanf("%d%d", W+i, M+i), s += M[i]*W[i];
ave = s / 2;
memset(F, 0, sizeof(int) * (ave+1));
for (i = 0; i < n; ++i)
{
int k = 1;
while (k < M[i])
{
for (int v = ave; v >= k*W[i]; --v)
F[v] = _max(F[v], F[v-k*W[i]]+W[i]*k);
M[i] = M[i] - k;
k = 2*k;
}
for (int v = ave; v >= M[i]*W[i]; --v)
F[v] = _max(F[v], F[v-M[i]*W[i]]+W[i]*M[i]);
}
printf("%d %d\n", s - F[ave], F[ave]);
}
return 0;
}