蓝桥杯原题:
题目描述:
在蓝桥王国中,有n名士兵,这些士兵需要接受一系列特殊的训练,以提升他们的战斗技能。对于第i名士兵来说,进行一次训练所需的成本为p2枚金币,而要想成为顶尖战士,他至少需要进行c2次训练。
为了确保训练的高效性,王国推出了一种组团训练的方案。该方案包含每位士兵所需的一次训练,且总共只需支付S枚金币(组团训练方案可以多次购买,即士兵可以进行多次组团训练)。
作为训练指挥官,请你计算出最少需要花费多少金币,才能使得所有的士兵都成为顶尖战士?
【输入格式】
输入的第一行包含两个整数n和S,用一个空格分隔,表示士兵的数量和进行一次组团训练所需的金币数。
接下来的n行,每行包含两个整数p2和c1,用一个空格分隔,表示第i名士兵进行一次训练的金币成本和要成为顶尖战士所需的训练次数。
【输出格式】
输出一行包含一个整数,表示使所有士兵成为顶尖战士所需的最少金币数。
【样例输入】
3 6
5 2
2 4
3 2
【样例输出】
16
【样例说明】
花费金币最少的训练方式为:进行2次组团训练,花费2×6=12枚金币, 此时士兵1,3已成为顶尖战士:再花费4枚金币,让士兵2进行两次训练,成为顶尖战士。总花费为12+4=16。
【评测用例规模与约定】
对于40%的评测用例,1 ≤ n ≤ 10^3,1 ≤ pi,ci ≤ 10^5 , 1 ≤ S ≤ 10^7。
对于所有评测用例, 1 ≤ n ≤ 10^5 , 1 ≤ pi,ci ≤ 10^6 , 1 ≤ S ≤ 10^10 。
主要思路
-
问题分析:
-
每个士兵需要完成一定次数的训练(
c[i]
)。 -
每次单独训练的成本是
p[i]
。 -
每次组团训练的成本是
S
,且组团训练可以覆盖所有士兵的一次训练。
-
-
贪心策略:
-
对于每个士兵,比较组团训练和单独训练的成本:
-
如果
S <= p[i]
,则组团训练更划算,优先使用组团训练。 -
否则,单独训练更划算,使用单独训练。
-
-
累加所有士兵的训练成本,得到总成本。
-
-
计算总成本:
-
统计所有士兵的组团训练次数,并计算其成本。
-
统计所有士兵的单独训练成本。
-
将两部分成本相加,得到最终结果。
-
注意点
-
数据范围:
-
S
的范围是1 ≤ S ≤ 10^10
,需要使用long long
来存储。 -
p[i]
和c[i]
的范围是1 ≤ p[i], c[i] ≤ 10^6
,需要注意计算过程中是否可能溢出。
-
-
贪心策略的正确性:
-
贪心策略的核心是每次选择当前最优的决策(组团训练或单独训练)。
-
需要确保贪心策略能够覆盖所有可能的情况,并且不会遗漏更优的解。
-
-
边界情况:
-
当
n = 1
时,只需要比较S
和p[0]
,选择更划算的方式。 -
当
S
非常大时,可能所有士兵都选择单独训练。 -
当
S
非常小时,可能所有士兵都选择组团训练。
-
代码
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
long long S; // S 可能很大,需要用 long long
cin >> n >> S;
vector<int> p(n);
vector<int> c(n);
for (int i = 0; i < n; i++) {
cin >> p[i] >> c[i];
}
long long total_cost = 0; // 总成本
long long group_times = 0; // 组团训练的次数
// 计算每个士兵的组团训练次数
for (int i = 0; i < n; i++) {
// 如果组团训练比单独训练更划算,则优先使用组团训练
if (S <= p[i]) {
group_times += c[i]; // 全部使用组团训练
} else {
// 否则,使用单独训练
total_cost += p[i] * c[i];
}
}
// 计算组团训练的总成本
total_cost += group_times * S;
cout << total_cost << endl;
return 0;
}
少年没有乌托邦,心向远方自明朗!
如果这个博客对你有帮助,给博主一个免费的点赞就是最大的帮助❤
欢迎各位点赞,收藏和关注哦❤
如果有疑问或有不同见解,欢迎在评论区留言❤
后续会继续更新大连理工大学相关课程和有关蓝桥杯的内容和示例
点赞加关注,学习不迷路,好,本次的学习就到这里啦!!!
ok,我们下次再见!