2024年GESP五级真题:贪心算法在游戏强化系统中的应用

一、问题背景分析
题目要求计算将武器1强化到最高等级的最小花费,规则如下:
每种武器有若干适配材料
可以花费金币修改材料适配的武器类型
武器1的适配材料数量必须严格多于其他武器
二、算法设计思路
三、完整代码解析(带详细注释)
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int n, m; // n种武器,m个材料
cin >> n >> m;
// cnt[i]表示武器i初始适配材料数量
vector<int> cnt(n+1, 0);
// cost[i]存储修改武器i材料的花费列表
vector<vector<int>> cost(n+1);
// 读取输入数据
for (int i = 0; i < m; i++) {
int p, c; // 材料适配武器p,修改花费c
cin >> p >> c;
cnt[p]++;
cost[p].push_back(c);
}
// 对每个武器的修改花费排序(升序)
for (int i = 1; i <= n; i++) {
sort(cost[i].begin(), cost[i].end());
}
long long res = 1e18; // 初始化为极大值
// 枚举武器1可能达到的材料数量k
for (int k = max(1, cnt[1]); k <= m; k++) {
long long sum = 0; // 当前k值下的总花费
int need = k - cnt[1]; // 还需获得的材料数
vector<int> pool; // 备选修改方案池
// 处理其他武器(2~n)
for (int i = 2; i <= n; i++) {
// 最多可以保留(k-1)个不改动
int can_take = max(0, cnt[i] - (k - 1));
// 贪心选择:取修改花费最小的can_take个
for (int j = 0; j < can_take; j++) {
sum += cost[i][j];
need--;
}
// 剩余材料放入备选池
for (int j = can_take; j < cost[i].size(); j++) {
pool.push_back(cost[i][j]);
}
}
// 如果还需要更多材料
if (need > 0) {
if (pool.size() < need) continue; // 无法满足条件
sort(pool.begin(), pool.end()); // 再次排序
for (int i = 0; i < need; i++) {
sum += pool[i]; // 选择最便宜的方案
}
}
res = min(res, sum); // 更新最小值
}
cout << res << endl;
return 0;
}四、关键知识点
五、性能优化要点
提前排序避免重复计算
使用vector减少内存分配开销
及时终止不可能的情况(continue)
合理选择数据结构(pool)
六、扩展思考
如果修改花费有上限如何处理?
如何记录具体的修改方案?
如果材料有不同类型限制怎么改进算法?
参考:GESP五级题武器强化
原创内容 转载请注明出处
