hduoj_1171(dp,01背包)

我以前遇到过一道类似的题目,不会。

这次看了题解之后有了思路,一次AC。

01背包的模板记错了,调了一会。


我是这样理解这个问题的。

不妨设总价值为SUM。

一方可以得到的价值为SUM/2 + C,另一方可以得到的价值为SUM/2 - C。

要使两方的价值尽可能接近,即2C尽可能小,即C尽可能小。

再仅看SUM/2 - C这一方,C尽可能小,就很像01背包问题了。


还有需要注意的一点是 这里每个物品的价值既是价值,同时还是该物品的体积,而背包的容量是SUM/2。

这样就保证在获得最大价值的同时(背包问题原型就是求解最大价值的),又使得总价值不超过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;
}

猜你喜欢

转载自blog.csdn.net/qq_32862515/article/details/80773327
今日推荐