题目大意:给你n个 有一定面值的硬币 把他分成两份 两份的差尽量少
解:从n个数中挑出一定数,使得他们的和尽量接近 sum/2, 裸01背包 ,将背包的容量看为sum/2,此处sum奇偶不影响结果,如果sum为奇数,设sum=2*k+1,sum/2=k+0.5,此时向上取整和向下取整最后得出的结果一样;
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
const int maxn=50010;
int dp[maxn];
int cost[110];
int main()
{
int t,sum,n;
cin>>t;
while (t--)
{
memset(dp,0,sizeof(dp));
cost[0]=0;
scanf("%d",&n);
sum=0;
for (int i=1;i<=n;i++)
{
scanf("%d",&cost[i]);
sum+=cost[i];
}
int k=sum/2;
for (int i=1;i<=n;i++)
for (int j=k;j>=cost[i];j--)
dp[j]=max(dp[j],dp[j-cost[i]]+cost[i]);
printf("%d\n",sum-2*(dp[k]));
}
}