我以前遇到过一道类似的题目,不会。
这次看了题解之后有了思路,一次AC。
01背包的模板记错了,调了一会。
我是这样理解这个问题的。
不妨设总价值为SUM。
一方可以得到的价值为SUM/2 + C,另一方可以得到的价值为SUM/2 - C。
要使两方的价值尽可能接近,即2C尽可能小,即C尽可能小。
再仅看SUM/2 - C这一方,C尽可能小,就很像01背包问题了。
还有需要注意的一点是 这里每个物品的价值既是价值,同时还是该物品的体积,而背包的容量是SUM/2。
扫描二维码关注公众号,回复:
1857600 查看本文章
这样就保证在获得最大价值的同时(背包问题原型就是求解最大价值的),又使得总价值不超过SUM/2(体积限制)。
AC代码如下。
#include <stdio.h>
#include <string.h>
int value[5001];
int dp[250001];
int main()
{
int N;
int V, M;
int i, j;
int k;
int sum;
while (scanf("%d", &N) && (N > 0))
{
k = 1;
sum = 0;
for (i = 1; i <= N; i++)
{
scanf("%d %d", &V, &M);
sum += V*M;
while (M--)
value[k++] = V;
}
memset(dp, 0, sizeof(dp));
for (i = 1; i < k; i++)
{
for (j = sum / 2; j >= value[i]; j--)
dp[j] = dp[j] > (dp[j - value[i]] + value[i]) ? dp[j] : (dp[j - value[i]] + value[i]);
}
printf("%d %d\n", sum - dp[sum / 2], dp[sum / 2]);
}
return 0;
}