题目大意:给出N种硬币和每种硬币的价值,现在问如何分这些硬币,使得两人得到的硬币价值差达到最小
解题思路:求出能达到的每种状态,然后从中间往左右扩
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define abs(x)((x)>0?(x):(-(x)))
const int N = 50010;
const int M = 110;
int val[M];
bool vis[N];
int n, Sum;
bool cmp(const int a, const int b) {
return a > b;
}
void init() {
scanf("%d", &n);
Sum = 0;
for (int i = 0; i < n; i++) {
scanf("%d", &val[i]);
Sum += val[i];
}
}
void solve() {
memset(vis, 0, sizeof(vis));
vis[0] = true;
sort(val, val + n, cmp);
for (int i = 0; i < n; i++)
for (int j = Sum - val[i]; j >= 0; j--)
if (vis[j] && !vis[j + val[i]]) vis[j + val[i]] = true;
int ave = (Sum + 1) / 2;
for (int i = 0; i <= ave; i++)
if (vis[ave - i]) {
printf("%d\n", max(Sum - ave + i, ave - i) - min(Sum - ave + i, ave - i));
break;
}
}
int main() {
int test;
scanf("%d", &test);
while (test--) {
init();
solve();
}
return 0;
}