学习C++从娃娃抓起!记录下蓝桥杯备考比赛学习过程中的题目,记录每一个瞬间。
附上汇总贴:蓝桥杯备考冲刺必刷题(C++) | 汇总-CSDN博客
【题目描述】
《明日方舟》是由鹰角网络所开发的一款策略塔防手机游戏。在每次的作战行动中,作为博士的你在战斗开始前需要合理分配干员进行战斗,以达到最高的战斗效率。
现有
n
n
n个干员,每个干员有攻击力和费用两个属性。同时有
m
m
m个敌人,每个敌人具有一定的生命值。你的任务是选择一些干员进行战斗,使得总费用不超过给定的预算B,同时击败所有敌人。
干员与敌人的关系如下:
- 若选择干员 i i i进行战斗, 则其可以在每一回合内对所有敌人造成 a t t a c k i attack_i attacki的伤害。
- 若敌人 j j j的生命值降为 0 0 0及以下,则该敌人被击败。
- 敌人不会行动,不会发起攻击。
请你选择合适的干员,计算最小回合数以击败所有敌人。
【输入】
第一行包含三个整数 n n n、 m m m和 B B B,表示干员数量、敌人数量和总预算 ( 1 ≤ n , m , B ≤ 1 0 4 ) (1\le n,m,B\le 10^4) (1≤n,m,B≤104)。
接下来 n n n行, 每行包括两个整数 a t t a c k i attack_i attacki 和 c o s t i cost_i costi, 表示第 i i i个干员的攻击力和费用 ( 1 ≤ a t t c k i , c o s t i ≤ 1 0 4 ) (1\le attck_i,cost_i\le 10^4) (1≤attcki,costi≤104)。
接下来 m m m行, 每行包括一个整数 l i f e j life_j lifej, 表示第 j j j个敌人的生命值 ( 1 ≤ l i f e j ≤ 1 0 4 ) (1\le life_j\le 10^4) (1≤lifej≤104)。
【输出】
输出一个整数,表示击败所有敌人所需的最小的回合数。若无法在预算内击败所有敌人,则输出 − 1 -1 −1。
【输入样例】
3 2 10
5 4
3 3
2 2
6
5
【输出样例】
1
【代码详解】
#include <bits/stdc++.h>
using namespace std;
int n, m, B, attack[10005], cost[10005], dp[10005], life, maxn=-1e9;
int main()
{
cin >> n >> m >> B;
for (int i=1; i<=n; i++) { // 输入n个干员的攻击力和费用
cin >> attack[i] >> cost[i];
}
for (int i=1; i<=n; i++) { // 使用01背包计算某个费用下的攻击力最大值
for (int j=B; j>=cost[i]; j--) {
dp[j] = max(dp[j], dp[j-cost[i]]+attack[i]);
}
}
for (int i=1; i<=m; i++) { // 计算敌人的最大生命值
cin >> life;
maxn = max(maxn, life);
}
if (dp[B]==0) { // 如果预算B下的最大攻击力为0
cout << -1 << endl; // 则无法击败所有敌人
return 0;
}
cout << ceil(1.0*maxn/dp[B]) << endl; // 否则计算最大生命值敌人会在几个回合被击败(向上取整)
return 0;
}
【运行结果】
3 2 10
5 4
3 3
2 2
6
5
1