uva562,把硬币分成两堆,两堆的差值尽量小
思路:就是把总值/2,然后尽量靠近这个值,每个硬币只能用一次,所以是0-1背包
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int maxn = 105;
int coin[maxn];
int d[maxn][maxn*500];
int main() {
int t,i,j;
int num;
int ssum;
scanf("%d", &t);
while(t--) {
ssum=0;
memset(d,0,sizeof(d));
memset(coin,0,sizeof(coin));
scanf("%d",&num);
for(i=1;i<=num;i++) {
scanf("%d",&coin[i]);
ssum+=coin[i];
}
int sum = ssum/2;
for(i=1; i<=num; i++) {
for(j=0; j<=sum; j++) {
d[i][j]=d[i-1][j];
if(j>=coin[i]) {
d[i][j]=d[i][j]>(d[i-1][j-coin[i]]+coin[i])?d[i][j]:(d[i-1][j-coin[i]]+coin[i]);
}
}
}
printf("%d\n",ssum - d[num][sum] - d[num][sum]);
}
return 0;
}