题目的意思就是给出很多数字.要分成两部分,两部分的和尽量接近..求两堆最小差多少.
就是个01背包的问题.
所有硬币和是sum .
那么我们要做的就是找值不超过 sum/2 的最大值.
原型就是01背包变形为 在重量不超过 sum / 2的情况下,放入最多的重量..
转移方程为 f[i][j] = max (f[i - 1][j] , f[i - 1][j - coin[i]] + coin [ i ] ) ;
AC代码 :
#include<stdio.h>
#include<string.h>
const int N = 105 ;
int coin[N];
int d[N][N * 500];
int main () {
int t;
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 (int i = 1 ; i <= num ;i++) {
scanf("%d",&coin[i]);
ssum += coin[i];
}
int sum = ssum / 2;
for (int i = 1 ; i <= num ;i++) {
for (int 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]);
}
}