0-1背包问题 + 滚动数组。
sum = x + y 不妨令 x <=y r = min(y-x) = min(sum - x * 2) 这样问题装换为单变量。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
using namespace std;
const int size = 500 * 100 + 10;
const int coin_size = 100 + 10;
int c[coin_size];
int d[size];
int main()
{
int T; scanf("%d" , &T);
while(T-- > 0)
{
int n , sum = 0;
scanf("%d" , &n);
for(int i = 0 ; i < n ; ++i)
{
scanf("%d" , c + i);
sum += c[i];
}
memset(d , 0 , sizeof(int) * (sum + 1));
for(int i = 0 ; i < n ; ++i)
{
for(int j = sum ; j >= 0 ; --j)
{
if(j >= c[i] * 2) d[j] = max(d[j] , d[j-c[i] * 2] + c[i] * 2);
}
}
printf("%d\n" , sum - d[sum]);
}
}