UVA 562 Dividing coins
题意:给你n个硬币,让你分成两堆,使得两堆的价值差最小。
分析:简单的01背包,转换一下,就是给你总价值的一半的背包空间,让你使背包里的价值尽可能大。有个小优化,就是总价值的一半都没有最大面值的硬币大时,直接就是最大面值*2-总价值。代码如下
#include<stdio.h>
#include<string.h>
#define mm(a) memset(a,0,sizeof(a))
#define ss(a) scanf("%d",&a)
#define For(i,q,s) for(int i=q
#define For1(i,q,s) for(int i=q
int n,a[105],f[25005],t,num,maxn,ans
int main()
{
ss(t)
while(t--)
{
maxn=-1
mm(f)
ans=num=0
ss(n)
For(i,1,n)
{
ss(a[i])
num+=a[i]
if(maxn<a[i])maxn=a[i]
}
if((num>>1)<=maxn)printf("%d\n",(maxn<<1)-num)
else
{
For(i,1,n)
For1(j,(num>>1),a[i])
if(f[j]<f[j-a[i]]+a[i])
f[j]=f[j-a[i]]+a[i]
ans=num-(f[num>>1]<<1)
printf("%d\n",ans)
}
}
return 0
}