【例题1】拔河比赛

【例题1】拔河比赛
题面

题目描述

在浙江师范大学 ACM 集训队,队员平时集训脑力劳动力比较重。为了劳逸结合,我们敬爱的韩老师准备了一场拔河比赛,让队员放松心情。

为了拔河比赛的公正性,韩老师提出以下要求:
\((1)\) 拔河比赛两边人数最多不能相差 \(1\)
\((2)\) 每个队员都有体重,我们要使两边比赛的人体重和相差最小。

现在有 \(N\) 个队员,韩老师想你帮忙分配,并且把分配后两边体重和之差最小值输出。

输入格式

首先输入 \(T\),表示有 \(T\) 组样例。

每个样例:

首先输入人数 \(N\),占一行。

后面跟着 \(N\) 个数,表示 \(N\) 个人的体重 \(W_1...W_n\)

输出格式

对于每个样例输出一行,一个整数表示两边体重之差的绝对值。

样例

样例输入

1
3
55 50 100

样例输出

5

数据范围与提示

对于 \(100\%\) 的数据,有 \(1\leq T \leq 50\)\(2\leq N\leq 20\)\(30\leq W_i \leq 120\)

分析
  • 可见题目的数据非常小
  • 那么我们没必要想复杂,直接暴力搜索即可。
  • 根据要求 \((1)\),我们可以知道人数始终有一方为 \(\lfloor \frac{n}{2} \rfloor\),另一方为 \(n-\lfloor \frac{n}{2} \rfloor\),也就是说我们需要将 \(n\) 对半选择。
  • 如果我们选出了 \(y\) 个人,这 \(y\) 个人的体重和为 \(z\)\(n\) 个人的体重和为 \(S\),那么当 \(y = \lfloor \frac{n}{2} \rfloor\) 的时候体重差就是 \(abs(z - (S - z)) = abs(2\times z - S)\),这时候只需要对每一个体重差进行最小值比较即可。
Code
#include <bits/stdc++.h>
using namespace std;

const int N = 30;

int T, n, w[N], ans = 0x3f3f3f3f, s;

void dfs(int x, int y, int z) {
    if (y == (n >> 1)) {
        ans = min(ans, abs(2 * z - s));
        return;
    }
    if (x > n)
        return;
    dfs(x + 1, y + 1, z + w[x]);
    dfs(x + 1, y, z);
}

int main(void) {
    cin >> T;
    while (T--) {
        cin >> n;
        memset(w, 0, sizeof(w));
        s = 0;
        for (int i = 1; i <= n; ++i) cin >> w[i], s += w[i];
        ans = 0x3f3f3f3f;
        dfs(1, 0, 0);
        cout << ans << endl;
    }

    return 0;
}
posted @ 2021-07-12 09:18  Juro  阅读(345)  评论(0编辑  收藏  举报