P3887 [GDOI2014] 世界杯
题目理解
P3887 [GDOI2014] 世界杯 是一道 贪心算法 题目,要求为多个足球阵型选择最优球员组合,使得每个阵型的 平均综合水平最高。关键点在于:
-
球员分类:守门员、后卫、中场、前锋。
-
阵型定义:如
4-5-1表示 4 后卫、5 中场、1 前锋(守门员固定 1 人)。 -
选择策略:按阵型顺序,每次从剩余球员中选择当前最优的对应位置球员。
解题思路
-
优先队列维护最优球员
-
用 大根堆(
priority_queue<int>)存储每个位置的球员能力值,确保每次取出的都是当前最优的球员。
-
-
按阵型顺序选择球员
-
对于每个阵型,依次从守门员、后卫、中场、前锋的堆顶取出所需数量的球员,并累加其能力值。
-
-
计算平均能力
-
总能力值除以 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; }
关键点分析
-
贪心策略
-
每次直接取当前剩余球员中的最优解(能力值最高),确保局部最优性。
-
-
数据结构选择
-
大根堆(
priority_queue<int>)保证每次取出的球员能力值最大。
-
-
球员分配逻辑
-
守门员固定 1 人,其他位置按阵型需求从队列中弹出,确保球员不会被重复选择。
-

浙公网安备 33010602011771号