UVa 562: Dividing Coins

题意:给一串数字作为硬币的币值,将这些硬币分给两个人A和B,要求越平均越好。

假设总钱数为Sum且A分得的钱不超过B,开数组dp,dp[i]表示A是否可以分得一些硬币使得其总钱数为i,dp[i]为1表示可以,0表示不可以。

dp数组初始化为0,dp[0]=1。然后分别对M个硬币枚举,判断dp是否可置为1即可。最后选择离Sum/2最近且dp[i]==1的i即可。

我的解题代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>

using namespace std;
#define min(a,b) (a<b?a:b);
#define maxn 100
#define INF 50000  //可以优化:#define INF 25000
int Coin[maxn];
int dp[INF+5];
int main()
{
	int N,M,Sum;
	cin >> N;
	while(N--)
	{
		cin >> M;
		Sum = 0;
		for(int i=0; i<M; i++) { cin >> Coin[i]; Sum += Coin[i]; }
		memset(dp,0,sizeof(dp));
		dp[0] = 1;

		for(int i=0; i<M; i++)
		{
			for(int j=Sum-Coin[i]; j>=0; j--)  //可以优化:for(int j=Sum/2-Coin[i]; j>=0; j--) 因为我们最后只要比Sum/2小的i值
			{
				if(dp[j]) dp[j+Coin[i]] = 1;
			}
		}

		for(int i=Sum/2; i>=0; i--) if(dp[i])
		{
			cout << Sum-2*i << endl;
			break;
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值