题目描述
现在给你一堆正整数,请你将其分为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);
}