I样
Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^
题目描述
这是个什么问题呢?DP,贪心,数据结构,图论,数论还是计算几何?管他呢,反正胖巨巨都会,虽然胖巨巨走得早。
现在有n个数Xi,现在你要把这些数分成两组A,B,使得abs(sum(A)-sum(B))尽可能的小,并且每个Xi必须且只能分
到一组中,每组至少包含一个数字。
到一组中,每组至少包含一个数字。
sum()表示计算累加和,abs()表示计算绝对值。
输入
输入有多组。对于每组数据:
第一行输入一个n(1 <= n <= 100),接下来的n行每行一个整数Xi(1 <= Xi <= 50)。
输出
对于每组数据,如果你能完成任务输出一个整数代表答案,否则输出-1。
示例输入
3 3 1 2 2 2 10
示例输出
0 8
解题心得: 题面来自SDUTOJ,前段时间面试时的笔试题原题,一个字都不带变的, 但额当时就是没想起来用背包,面试官
更是用二分给我讲了一遍,到现在我也没明白面试官当时是怎么个意思,回来后给学弟们一说,各位ACM大神果断给出了答案:背包!
OJ原题! 然后就抛给了我上面这个题面, 我那个后悔啊! 如果当时能想起来用背包然后再弱弱的给面试官说:sorry,我还有个更
优的。。这该多diao啊你说说,哎 好了不做梦了,从现在开始努力吧!
上代码:
#include<string.h>
#include<cmath>
using namespace std;
int main()
{
int n,i,j,a[11000],dp[10010],sum;
while(cin>>n)
{
memset(dp,0,sizeof(dp));
sum=0;
for(i=0;i<n;i++)
{
cin>>a[i];
sum+=a[i];
}
int tt=sum/2;
for(i=0;i<n;i++)
{
for(j=tt;j>=0;j--)
{
if(j>=a[i])
{
dp[j]=max(dp[j],(dp[j-a[i]]+a[i]));
}
}
}
if(n==1)
{
cout<<"-1"<<endl;
}
else
{
sum=abs(sum-2*dp[tt]);
cout<<sum<<endl;
}
}
return 0;
}