http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=503
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=30000;
const int M=105;
bool ex[N];
int coin[M];
int main()
{
int n,m,total;
cin>>n;
while(n--)
{
cin>>m;
total=0;
for(int i=1;i<=m;i++)
{
cin>>coin[i];
total+=coin[i];
}
memset(ex,0,sizeof(ex));
ex[0]=1;
for(int t=1;t<=m;t++)
for(int v=total/2;v>=coin[t];v--)
{
ex[v]=(ex[v-coin[t]]|ex[v]);//状态方程
}
int mid=total/2;
while(ex[mid]==0) mid--;
cout<<total-mid-mid<<endl;
}
return 0;
}
基本思想:假设所有硬币的和为total,如果可以用这些硬币中的某些凑成 value ,则其余的硬币可以凑成 total-value。在这样的指导思想下,我们只需从total/2处 往下查询