ZOJ 2868 Incredible Cows

63 篇文章 0 订阅

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

0
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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值