这个题最重要的是一种求组合数的方法。求出所有硬币的和sum后用
memset(f,0,sizeof(f));
f[0]=1;
for(int i=0; i<n; i++)
{
for(int j=sum; j>=coin[i]; j--)
{
if(f[j-coin[i]])
f[j]=1;
}
}
求所有可能的子数列的和,因为如果在j在0——sum范围内,并且j-coin[i]是某一个子数列的和,那么j-coin[i]+coin[i]也是一个子数列的和。i=0时得到的是f[coin[i]]=1,i=1时得到的是coin[0]+coin[1]和coin[1],i==2时得到的是coin[2],coin[0]+coin[2],coin[1]+coin[2],coin[1]+coin[2]+coin[3],……这样就能得到所有子数列的和了。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdlib>
#define MAXN 110
using namespace std;
int main()
{
// freopen("in.txt","r",stdin);
int n,coin[MAXN],cas,f[50003],minn,sum;
cin>>cas;
while(cas--)
{
cin>>n;
sum=0;
for(int i=0; i<n; i++)
{
cin>>coin[i];
sum+=coin[i];
}
memset(f,0,sizeof(f));
f[0]=1;
for(int i=0; i<n; i++)
{
for(int j=sum; j>=coin[i]; j--)
{
if(f[j-coin[i]])
f[j]=1;
}
}
minn=0x7fffffff;
for(int i=0; i<=sum; i++)
{
if(f[i])
{
int temp=abs(sum-i-i);
minn=min(temp,minn);
}
}
cout<<minn<<endl;
}
return 0;
}