您的位置:首页 > 其它

HHUOJ 1017 最小差(01背包)

2016-09-16 11:38 113 查看

1017: 最小差

时间限制: 1 Sec  内存限制: 128 MB

提交: 20  解决: 5

题目描述

假设有n个正整数a1,a2,a3…an,希望将这些数分成两组,使得两组的和差值最小。

输入

第一行输入整数m(0<m<=100),代表测试用例的数量。

接下来每个用例由两行组成,第一行是一个整数n(1<n<=100),表示整数的个数,第二行包含n个正整数,且最大不超过100。

输出

输出最小的差的绝对值。

样例输入

263 2 3 4 2 951 1 1 1 10

样例输出

16

提示

来源

河海ACM前辈-裴正

思路:

题意很清楚,n个数,分两组,两组的差最接近0。很自然的想到这是在类似于取东西,看怎么取得平均(就是说要使两组数都尽可能的接近sum/2)。所以只需要对一组进行求算使它最接近sum/2,那样的话另一组自然也是最接近的。这就是典型的01背包问题了,sum/2的体积求最多可以装多少。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int v[100+2];
int dp[100+2][100+2];

int main()
{
//freopen("in.txt","r",stdin);
int m;
cin>>m;
while(m--)
{
int n;
scanf("%d",&n);
int sum=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&v[i]);
sum+=v[i];
}
int summ=sum/2;
memset(dp,0,sizeof(dp));
dp[0][0]=0;
for(int i=1;i<=n;i++)
for(int j=summ;j>=0;j--)
{
if(j>=v[i])dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]]+v[i]);
else dp[i][j]=dp[i-1][j];
}
printf("%d\n",abs(sum-2*dp
[summ]));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: