神奇的分组(c语言DP)

题目描述

现在给你一堆正整数,请你将其分为2组,要求2组的和相差最小。

例如:1 2 3 4 5,将1 2 4分为1组,3 5分为1组,两组和相差1,是所有方案中相差最少的。

输入

单组输入,每次输入两行
第1行:一个数N,N为正整数的数量。
第2 - N+1行,N个正整数。
(N <= 100, 所有正整数的和 <= 10000)

输出

输出这个最小差

样例输入 

5
1 2 3 4 5

样例输出 

1

1.这个题目开始看也是一脸懵,然后去看了一下其他人写的,理解了思路。这题是一个背包,大家可以去看看01背包 ,也可以看一下我写的装箱问题,是按这个思路来的。

2,为什么说是背包问题呢,我们可以理解为,是要装到2个背包里面,那么为了满足题意这个背包的容量应该为多少最好?当然是总和/2,这样的话就能满足题意啦。虽然我们不一定能取到总和/2,但是越靠近这个数,说明它们相差越小。

3.我们暂时只装一个背包(为什么这样,别着急),按照题意,我们需要开辟一个dp[10000],当作背包,开数组的时候一定要记得开大一点,我开的是10010,然后按照取舍,放入背包,具体的大家就去看看我上面所说的装箱问题即可。

4.当我们装好一个背包,我们很清楚的知道,另外一个背包的容量一定是总和减去这个背包能取的最大值。给大家做了一个图片,更好理解:(其中maxres=sum/2的)

所以最终答案一定会是sum-2*背包最大容量 。

代码如下:

#include<stdio.h>
#define N 10010
int dp[N];
int max(int a,int b)
{
	if(a>b) return a;
	return b;
}
int main()
{
	int n,a[110]={0},i,sum=0,maxres,j;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		sum+=a[i];
	}
	maxres=sum/2;
	for(i=1;i<=n;i++)
	{
		for(j=maxres;j>=a[i];j--)
		{
			dp[j]=max(dp[j],dp[dp[j-a[i]]]+a[i]);
		}
	}
	printf("%d\n",sum-dp[maxres]*2);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值