天天看点

ZOJ 2868 Incredible Cows

Incredible Cows

Time Limit: 2 Seconds      

Memory Limit: 32768 KB

Farmer John is well known for his great cows. Recently, the cows have decided to participate in the Incredible Cows Puzzle Contest (ICPC).

Farmer John wants to divide the cows into two teams, and he wants to minimize the difference of Puzzle Solving Power of two teams.

Puzzle Solving Power of a team is sum of Puzzle Solving Power of cows forming that team.

Help F.J. to find the minimum difference!

Input

The first line of input consists of a single integer T, the number of test-cases. Each test-case consists of a line containing n (2 <= n <= 34), number of cows. n lines follow. i-th line contains the Puzzle Solving Power of i-th cow. Puzzle Solving Power of a cow is a non-negative number less than 10,000,000. There is a blank line between two consecutive test-cases.

Output

For each test-case, output a line containing the minimum difference which can be achieved.

Sample Input

2

3

12

6

6

10

123

455

1000

403

234

554

129

454

84

11

Sample Output

5

分两组要求差值最小,数字范围太大,又不能直接dfs

#include<cstdio>
#include<cmath>
#include<vector>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn = 200005;
int T, n, a[2][maxn], m[2];
int f1[maxn], f2[maxn], t[2], ans;

void dfs(int flag, int x, int y)
{
    if (x > m[flag])
    {
        if (flag) f2[t[flag]] = y;
        else f1[t[flag]] = y;
        t[flag]++;
        return;
    }
    dfs(flag, x + 1, abs(y + a[flag][x]));
    dfs(flag, x + 1, abs(y - a[flag][x]));
}

int main()
{
    scanf("%d", &T);
    while (T--)
    {
        scanf("%d", &n);
        t[0] = t[1] = 0;
        m[0] = (n + 1) / 2;    m[1] = n / 2;
        for (int i = 1; i <= m[0]; i++) scanf("%d", &a[0][i]);
        for (int i = 1; i <= m[1]; i++) scanf("%d", &a[1][i]);
        dfs(0, 1, 0);
        dfs(1, 1, 0);
        sort(f1, f1 + t[0]);
        sort(f2, f2 + t[1]);
        ans = 0x7FFFFFFF;
        for (int i = 0; i < t[0]; i++)
        {
            int k = lower_bound(f2, f2 + t[1], f1[i]) - f2;
            if (k < t[1]) ans = min(ans, f2[k] - f1[i]);
        }
        for (int i = 0; i < t[1]; i++)
        {
            int k = lower_bound(f1, f1 + t[0], f2[i]) - f1;
            if (k < t[0]) ans = min(ans, f1[k] - f2[i]);
        }
        printf("%d\n", ans);
    }
    return 0;
}