列表

详情


WY75. 篮球队

描述

小Q是篮球训练队的教练,篮球队新加入了N名队员,第i名队员的篮球水平值为ai
小Q现在要把他们按照以下的要求分为A队和B队进行训练:
1、A队的队员水平值之和严格大于B队的队员水平值之和
2、对于A队中的任意一名队员,如果把他分配到B队,A队的水平值之和就会严格小于B队的水平值之和。
3、每个队员必须要加入一个队伍
小Q现在想知道有多少种方案可以按照以上要求完成分队。

输入描述

输入包括两行, 输入的第一行为一个正整数n(2 <= N <= 50), 表示队员的数量。
第二行包括N个正整数 ai(1 <= ai <= 6 x 104), 表示每名队员的篮球水平值, 以空格分割。

输出描述

输出一个正整数, 表示方案数。

示例1

输入:

4
5 4 7 6

输出:

2

原站题解

C++ 解法, 执行用时: 32ms, 内存消耗: 6660KB, 提交时间: 2020-10-28

#include <bits/stdc++.h>
#define MAX_N 50
using namespace std;
typedef int_fast64_t INT64;
int n, nums[MAX_N];
INT64 dp[MAX_N * 30000 + 5] = {1};
   
int gcd(int x, int y) { return y ? gcd(y, x % y) : x; }
   
INT64 solve() {
    int sum = 0, g = *nums;
    for (int i = 1; i < n; ++i) g = gcd(g, nums[i]);
    for (int i = 0; i < n; ++i) sum += nums[i] /= g;
    sort(nums, nums + n);
    INT64 ans = nums[n - 1] > sum / 2 ? 1 : 0;
    for (int i = n - 1; i > 0; --i) {
        for (int j = (sum - 1) / 2; j >= nums[i]; --j) {
            dp[j] += dp[j - nums[i]];
        }
        for (int j = sum / 2 - nums[i - 1] + 1, s = (sum + 1) / 2;
             j < s; ++j) {
            ans += dp[j];
        }
    }
    return ans;
}
   
int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) scanf("%d", nums + i);
    printf("%" PRIdFAST64 "\n", solve());
    return 0;
}

C++ 解法, 执行用时: 33ms, 内存消耗: 6604KB, 提交时间: 2020-10-29

#include <bits/stdc++.h>
#define MAX_N 50
using namespace std;
typedef int_fast64_t INT64;
int n, nums[MAX_N];
INT64 dp[MAX_N * 30000 + 5] = {1};
   
int gcd(int x, int y) { return y ? gcd(y, x % y) : x; }
   
INT64 solve() {
    int sum = 0, g = *nums;
    for (int i = 1; i < n; ++i) g = gcd(g, nums[i]);
    for (int i = 0; i < n; ++i) sum += nums[i] /= g;
    sort(nums, nums + n);
    INT64 ans = nums[n - 1] > sum / 2 ? 1 : 0;
    for (int i = n - 1; i > 0; --i) {
        for (int j = (sum - 1) / 2; j >= nums[i]; --j) {
            dp[j] += dp[j - nums[i]];
        }
        for (int j = sum / 2 - nums[i - 1] + 1, s = (sum + 1) / 2;
             j < s; ++j) {
            ans += dp[j];
        }
    }
    return ans;
}
   
int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) scanf("%d", nums + i);
    printf("%" PRIdFAST64 "\n", solve());
    return 0;
}

上一题