P3887 [GDOI2014] 世界杯

题目理解

P3887 [GDOI2014] 世界杯 是一道 贪心算法 题目,要求为多个足球阵型选择最优球员组合,使得每个阵型的 平均综合水平最高。关键点在于:

  1. 球员分类:守门员、后卫、中场、前锋。

  2. 阵型定义:如 4-5-1 表示 4 后卫、5 中场、1 前锋(守门员固定 1 人)。

  3. 选择策略:按阵型顺序,每次从剩余球员中选择当前最优的对应位置球员。

解题思路

  1. 优先队列维护最优球员

    • 用 大根堆(priority_queue<int>)存储每个位置的球员能力值,确保每次取出的都是当前最优的球员。

  2. 按阵型顺序选择球员

    • 对于每个阵型,依次从守门员、后卫、中场、前锋的堆顶取出所需数量的球员,并累加其能力值。

  3. 计算平均能力

    • 总能力值除以 11(11 人阵容),输出四舍五入到小数点后 2 位的结果。


代码注释

#include<bits/stdc++.h>
using namespace std;

int k, d, m, f;  // 守门员、后卫、中场、前锋的人数
priority_queue<int> q1, q2, q3, q4;  // 大根堆:q1-守门员,q2-后卫,q3-中场,q4-前锋

int main() {
    // 输入球员数据并存入优先队列
    cin >> k >> d >> m >> f;
    for(int i = 1; i <= k; i++) {
        int x; cin >> x;
        q1.push(x);  // 守门员按能力降序排列
    }
    for(int i = 1; i <= d; i++) {
        int x; cin >> x;
        q2.push(x);  // 后卫按能力降序排列
    }
    for(int i = 1; i <= m; i++) {
        int x; cin >> x;
        q3.push(x);  // 中场按能力降序排列
    }
    for(int i = 1; i <= f; i++) {
        int x; cin >> x;
        q4.push(x);  // 前锋按能力降序排列
    }

    int Q; cin >> Q;  // 阵型数量
    while(Q--) {
        int a, b, c; cin >> a >> b >> c;  // 当前阵型:a后卫, b中场, c前锋
        double ans = 0;

        // 选择1个最优守门员
        ans += q1.top(); q1.pop();

        // 选择a个最优后卫
        for(int i = 1; i <= a; i++) {
            ans += q2.top(); q2.pop();
        }

        // 选择b个最优中场
        for(int i = 1; i <= b; i++) {
            ans += q3.top(); q3.pop();
        }

        // 选择c个最优前锋
        for(int i = 1; i <= c; i++) {
            ans += q4.top(); q4.pop();
        }

        // 输出平均能力(11人阵容)
        printf("%.2f\n", ans / 11);
    }
    return 0;
}

关键点分析

  1. 贪心策略

    • 每次直接取当前剩余球员中的最优解(能力值最高),确保局部最优性。

  2. 数据结构选择

    • 大根堆(priority_queue<int>)保证每次取出的球员能力值最大。

  3. 球员分配逻辑

    • 守门员固定 1 人,其他位置按阵型需求从队列中弹出,确保球员不会被重复选择。

 
posted @ 2025-05-30 15:40  CRt0729  阅读(13)  评论(0)    收藏  举报