Kas题解报告

传送门:

1、题目:洛谷:kas

题目描述:

Kile和 Pogi在逛街的时候,捡到N张纸币。确定了无法找到失主之后,他俩决定分了这些钱。他们希望俩人分得的金额相同,所以他俩用这样的方式分钱。如果这些纸币可以被均分,那是最好不过了。可是分到最后,俩人分的金额有可能不同(尽量多的均分),而谁也不愿意是被分少的那一个。

他们也不可能把分不匀的钞票丢掉,于是他俩决定到最近的赌场去,他俩把剩余的钱都压上,两个小伙伴的运气实在是太好了,他们最终得到两倍的赌注。这样,两个小伙伴就能把他俩赢的钱均分成两份了。

由于好事来的太突然了,以至于这两个孩子已经失去了数学能力。请你帮助他们计算出他俩每个人能带回家多少钱。

输入格式:

第 1 行输入包含一个整数N,表示纸币的张数;

接下来的N行,每行包含一个正整数Ci表示第 i 张纸币的价值。

输出格式:

输出共一行一个整数,输出他俩每人能带回家多少钱。

样例输入:
样例1
4
2
3
1
6

样例2
5
2
3
5
8
13
样例输出:
样例1
6

样例2
18
提示:

【样例1说明】Kile将得到纸币2,3,1,Pogi将得到纸币6。

【样例2说明】Kile得到了纸币5和8,Pogi得到了纸币13。剩下的纸币是2和3,两个小伙伴在赌场中翻倍得到了2,2,3,3。所以每个人得到的钱是13+5=18。

【数据规模】

对于50%的数据: 1≤N≤15;

对于70%的数据: 1≤N≤50;所有纸币的总数不超过1,000;

对于100%的数据:1≤N≤500;所有纸币的总数不超过100,000;

提供思路答案:

注释请参考:

#include<bits/stdc++.h>
using namespace std;
int n,x,sum;
int dp[505][100005];
int main(){
	scanf("%d",&n);
	//dp[i][j]表示用前i张钱令两人取的钱的差值为j的取的钱的总和最大值。
	memset( dp,-0x3f,sizeof(dp) );//这里为何要清负数?
	//因为可能你在转移的时候,有一些DP的值根本没有更新。
	dp[0][0]=0;  	
	for (int i = 1;i <= n;i ++){
		scanf ("%d", &x);
		sum += x;
		for(int j = 0; j <= sum; j ++){
			dp[i][j] = dp[i - 1][j];
			if (  dp[i - 1][j + x] + x > dp[i][j])
				dp[i][j] = dp[i - 1][j + x] + x;
			if (  j >= x && dp[i - 1][  j - x ] + x > dp[i][j])
				dp[i][j] = dp[i - 1][j - x ] + x;
			if (  x >= j && dp[i - 1][ x - j ] + x  > dp[i][j])
				dp[i][j] = dp[i - 1][ x - j ] + x;
		}
	}
	printf( "%d", sum - dp[n][0] / 2 );
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值