**战士技能规划设计**
2026 华为OD机试真题 8月2日华为OD上机新系统考试真题 200 分题型
点击查看华为 OD 机试真题完整目录:2026最新华为OD机试新系统卷 + 双机位C卷 真题题库目录|全覆盖题库 + 逐点算法考点详解
题目描述
你为一款动作游戏设计战士角色的技能:战士每个技能会消耗不同能量,释放技能有 2 个约束:连续释放技能数量不能超过 m 个,技能能量总和不能超过能量上限 k;如果超过则必须中断当前技能,进入调息状态(即分段)。
战士有一项爆发技巧:在单次战斗中有一次能量上限翻倍至 2k 的机会,此项场景下战士需使用连续的 w 个技能(技能数量限制 m 依然生效)。
任务目标:
作为战术分析师,你需要为战士规划最优的技能释放序列。给定一套技能的能量消耗列表 a,请计算在合理使用爆发机会(或选择不使用)的前提下,释放完所有技能所需的最少分段数(即最少调息次数)。
若存在某个技能的能耗过高,即使开启爆发也无法释放(大于 2k),则判定为无解,返回 −1。
2026 华为OD机试真题 8月2日华为OD上机新系统考试真题 200 分题型
点击查看华为 OD 机试真题完整目录:2026最新华为OD机试新系统卷 + 双机位C卷 真题题库目录|全覆盖题库 + 逐点算法考点详解
输入描述
输入参数说明:
- k: 能量上限,正整数
- m: 单次调息最大技能数,正整数
- w: 爆发持续技能数,正整数
- a: 技能能量消耗列表,长度为 n,每个元素为正整数
输入为一行,格式为:
k,m,w,[a1,a2,...,an]
数组中允许出现空格,例如 [1, 1, 1]。
数据范围:
- n 为技能数量,即 a 的长度
- 1≤w≤n
- 1≤n≤100000
- 1≤m≤n
- 1≤k≤1000000000
- 1≤a[i]≤1000000000
输出描述
输出满足条件的最少分段数(最少调息次数)。若无解则输出 −1。
示例1
输入
5,3,2,[3,4,3,4]
输出
3
说明
爆发窗口覆盖索引 0∼1 [3,4] 为 1 段,剩余 [3],[4] 各 1 段 → 共 3 段。
示例2
输入
10,5,3,[1, 1, 1, 1, 1]
输出
1
说明
sum(a)=5≤k=10 且 n=5≤m=5,无需爆发即可 1 段放完。若开启爆发,窗口最多覆盖 w=3 个技能,剩余 1 个技能需另开 1 段,反而变成 2 段,因此不使用爆发更优。
解题思路
核心思想
普通释放时,每一段最多包含 m 个技能,且能量和不超过 k。由于所有技能能耗都是正数,对于固定右端点,最后一段越长越不差,因此可以用滑动窗口在线性时间内求出前缀最少分段数;同理从右往左求后缀最少分段数。
爆发只能使用一次,并且必须覆盖连续 w 个技能,这 w 个技能单独作为一个分段,能量上限为 2k,技能数量限制仍为 m。枚举爆发窗口位置,答案为:
窗口左侧普通最少段数 + 1 + 窗口右侧普通最少段数
同时还要和“不使用爆发”的方案取最小值。
算法步骤
- 如果存在
a[i] > 2k,即使爆发也无法释放,直接返回-1。 - 用滑动窗口构造
prefix[i]:普通状态下释放前i个技能的最少分段数。 - 用反向滑动窗口构造
suffix[i]:普通状态下释放a[i...n-1]的最少分段数。 - 初始答案为
prefix[n],表示完全不使用爆发。 - 若
w <= m,枚举每个长度为w的窗口;当窗口能量和不超过2k且左右两侧都能普通释放时,更新答案。 - 若最终仍无法释放,输出
-1,否则输出最小分段数。
复杂度分析
设技能数量为 n。
- 时间复杂度:
O(n),前缀、后缀和爆发窗口各线性扫描一次。 - 空间复杂度:
O(n),用于保存prefix和 `suff