洛谷B4051 [GESP202409 五级] 小杨的武器 题解
B4051 [GESP202409 五级] 小杨的武器
题目传送门👉 https://www.luogu.com.cn/problem/B4051#ide
题目背景
对应的选择、判断题:https://ti.luogu.com.cn/problemset/1161
题目描述
小杨有 n 种不同的武器,他对第 i 种武器的初始熟练度为 c_i。
小杨会依次参加 m 场战斗,每场战斗小杨只能且必须选择一种武器使用,假设小杨使用了第 \(i\) 种武器参加了第 \(j\) 场战斗,战斗前该武器的熟练度为 c'_i,则战斗后小杨对该武器的熟练度会变为 c'_i + a_j。需要注意的是,a_j 可能是正数,0 或负数,这意味着小杨参加战斗后对武器的熟练度可能会提高,也可能会不变,还有可能降低。
小杨想请你编写程序帮他计算出如何选择武器才能使得 m 场战斗后,自己对 n 种武器的熟练度的最大值尽可能大。
输入格式
第一行包含两个正整数 n,m,含义如题面所示。
第二行包含 n 个正整数 c_1, c_2,. . . . . c_n,代表小杨对武器的初始熟练度。
第三行包含 m 个正整数 a_1, a_2,. . . . . a_m,代表每场战斗后武器熟练度的变化值。
输出格式
输出一个整数,代表 m 场战斗后小杨对 n 种武器的熟练度的最大值最大是多少。
输入输出样例 #1
输入 #1
2 2
9 9
1 -1
输出 #1
10
说明/提示
样例 1 解释
一种最优的选择方案为,第一场战斗小杨选择第一种武器,第二场战斗小杨选择第二种武器。
数据规模与约定
| 子任务编号 | 数据点占比 | \(n\) | \(m\) |
|---|---|---|---|
| \(1\) | \(20\%\) | \(=1\) | \(\leq 10^5\) |
| \(2\) | \(20\%\) | \(\leq 10^5\) | \(=2\) |
| \(3\) | \(60\%\) | \(\leq 10^5\) | \(\leq 10^5\) |
对全部的测试数据,保证 \(1 \leq n, m \leq 10^5\),\(-10^4 \leq c_i, a_i \leq 10^4\)。
解题思路:
本题采用贪心算法
1.题目转化:
本题要求为熟练度的最大值最大,而并非每个武器的具体值
2.分配策略:
-
如果想要让最大值最大,就需要尽量让熟练度最高的武器在战斗中让熟练度增长
-
负数或0的变化留给其他武器使用,这样并不会影响到最大值
3.特殊情况:
当n=1时,仅有一把武器,所以这把武器必须参加所有战斗
4.算法步骤:
-
在输入武器原始熟练度时找出最大值
-
如果仅有一把武器,将战斗时获得的熟练度累加求和后与原始熟练度相加
-
如果有不止一把武器,就将战斗时获得的熟练度中取正数与原始熟练度相加
-
最终输出结果
5.代码实现:
AC记录:https://www.luogu.com.cn/record/280320374
点击查看代码
#include<bits/stdc++.h>//万能头文件
using namespace std;
int main() {
int n,m;cin>>n>>m;//数据读入
int maxx=-2147483648,h;//maxx为所有武器熟练度中的最大值
for(int i=1;i<=n;i++) {
int x;cin>>x;//输入武器熟练度
maxx=max(maxx,x);//更新最大值
}
h=maxx;//h用于n为1时的累加求和
for(int i=1;i<=m;i++) {
int x;cin>>x;//输入战斗后增加的熟练度
if(x>0) maxx+=x;//如果战斗后增加的熟练度为正数(即大于0的数),则使用原始熟练度最大的武器参加本场战斗
h+=x;//将h更新
}
if(n!=1) cout<<maxx;//正常情况:不止一个武器
else cout<<h;//特殊情况:仅有一个武器
return 0;
}

浙公网安备 33010602011771号