MVP争夺战 [100分]

题目

058851ca-9d32-4e23-9ba4-1abc1a80e372

思路

  设MVP得分为 \(scores\)\(t\) 场的总得分为 \(total\),那么可以产生 \(total / scores\) 位MVP。

  接着,问题就可以转化为,我们有 \(total / scores\) 位MVP,如何分配每一场的分数才能使每一位MVP的分数刚好为 \(scores\)

  由此可见,涉及方案问题,考虑使用 \(DFS + 剪枝\) 来解决。

  首先,我们对可能的MVP人数进行枚举,在这个过程中,由人数 \(s = total / scores\) 我们可以得知,人数 \(s\) 一定为总得分 \(total\) 的因子,因此对于 \(total \;\%\; s \neq 0\) 的情况便可以进行剪枝。

  接着,我们考虑 \(DFS\) 过程中的剪枝。我们将 \(DFS\) 的过程看作要填满 \(n\) 个容量一样的桶,那么首先我们将 \(t\) 个物品降序排列,先考虑体积大的物体,那么我们就可以更快的填满桶,或更快地发现当前方案不可行。

  同时,如果当前桶的剩余容量与上一个桶的剩余容量相同时,可以直接跳过当前桶,因为如果当前桶可以放入该物品,那么前一个桶也一定可以,之所以枚举到当前桶一定证明他在前一个桶中已经失败了,而在当前与前一个桶容量相同的桶中也一定会失败。

Code

#include <bits/stdc++.h>

#define int long long
#define pii std::pair<int, int>

#define fir first
#define sec second

#define endl '\n'

#define no std::cout << "NO\n"
#define yes std::cout << "YES\n"

#define all(x) x.begin(), x.end()

const int inf = 1e9;
const int mod = 1e9+7;

bool dfs(std::vector<int>& p, std::vector<int>& mark, int scores, int idx) {
    
    if(idx == p.size()) {
        return true;
    }

    int now = p[idx];
    for(int i = 0; i < mark.size(); i ++ ) {
        if(i > 0 && mark[i] == mark[i-1]) continue;

        if(mark[i] + now <= scores) {
            mark[i] += now;

            if(dfs(p, mark, scores, idx+1)) {
                return true;
            }

            mark[i] -= now;
        }
    }

    return false;
}

bool check(int n, int scores, std::vector<int>& p) {
    std::vector<int> mark(n, 0);
    return dfs(p, mark, scores, 0);
}

void solve() {
    int t;
    std::cin >> t;

    std::vector<int> p(t);
    for(int i = 0; i < t; i ++ ) {
        std::cin >> p[i];
    }

    int total = accumulate(all(p), 0);

    std::sort(all(p), std::greater<int>());

    for(int s = t; s >= 1; s -- ) {
        if(total % s != 0) continue;
        if(total / s < p[0]) continue;

        if(check(s, total / s, p)) {
            std::cout << total / s << '\n';
            return;
        }
    }
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);

    int _ = 1;
    //std::cin >> _;

    while(_--) {
        solve();
    }

    return 0;
}
posted @ 2025-07-03 02:23  算法蒟蒻沐小白  阅读(42)  评论(0)    收藏  举报