一、题目解析
题目描述
在游戏中,每个角色有如下属性:
- 能量值 a[i]a[i]a[i](两两不同)。
- 击败其他角色后可获得分数 b[i]b[i]b[i]。
规则:
- 每个角色最多可以击败 mmm 个其他角色。
- 能量值大的角色可以击败能量值小的角色。
- 最终目标是计算每个角色可以获得的最大分数。
解题思路
- 排序:按照能量值 a[i]a[i]a[i] 从小到大排序。排序后,能量大的角色依次击败比它弱的角色。
- 维护优先队列(堆) :对每个角色,维护它可以击败的 mmm 个角色的最大得分集合,使用堆结构高效获取得分。
- 反向计算:从能量值最大的角色开始计算它的最大得分,并将其分数更新到堆中供后续角色计算。
二、代码实现
以下是代码详细解析:
python
复制代码
import heapq
def solution(n: int, m: int, a: list, b: list) -> list:
# 将角色按能量值排序
characters = sorted(zip(a, b), key=lambda x: x[0])
# 记录结果数组
max_scores = [0] * n
# 优先队列(小顶堆)存储可以被击败的角色分数
heap = []
heap_sum = 0 # 堆中分数和
# 逆序遍历,从能量大的角色开始
for i in range(n - 1, -1, -1):
energy, score = characters[i]
# 当前角色分数是其自身分数 + 堆中分数
max_scores[i] = score + heap_sum
# 将当前角色分数加入堆中
heapq.heappush(heap, score)
heap_sum += score
# 如果堆大小超过 m,移除分数最小的
if len(heap) > m:
heap_sum -= heapq.heappop(heap)
# 根据排序前的索引还原结果
index_mapping = {value: i for i, value in enumerate(a)}
result = [0] * n
for i, (energy, score) in enumerate(characters):
result[index_mapping[energy]] = max_scores[i]
return result
三、测试用例
python
复制代码
if __name__ == '__main__':
# 示例 1
print(solution(5, 3, [1, 3, 5, 2, 4], [1, 2, 3, 4, 5]))
# 输出: [0, 5, 11, 1, 7]
# 示例 2
print(solution(4, 2, [10, 20, 30, 40], [2, 4, 6, 8]))
# 输出: [0, 2, 6, 10]
# 示例 3
print(solution(6, 1, [6, 12, 18, 24, 30, 36], [5, 10, 15, 20, 25, 30]))
# 输出: [0, 5, 10, 15, 20, 25]
四、知识总结
- 堆的应用
小顶堆(优先队列)可以高效维护动态数据集合中的最小值或最大值,适合处理类似“保留前 kkk 个最优解”的场景。 - 排序后的索引还原
在处理排序问题时,记录原始索引可以在排序后正确还原答案。 - 动态规划的思想
本题中,逆序遍历的过程中动态更新堆,计算当前最大得分,这是一种动态规划的思路。