问题描述
题目解析
题目描述了一个游戏场景,小E面对一系列的怪物,每个怪物有特定的血量和攻击力。小E需要按顺序击败这些怪物,但必须符合一些规则:
- 小E可以击败一个血量和攻击力都小于她当前属性的怪物。
- 第一个击败的怪物必须满足其血量小于小E的初始血量且攻击力小于小E的初始攻击力。
- 击败怪物后,小E会获得该怪物的属性值(即血量和攻击力都会更新为击败的怪物的属性值)。
- 击败的怪物序列中,后一个怪物的血量和攻击力都必须严格大于前一个怪物。
小E想知道,她最多能击败多少怪物。
思路
这是一个典型的动态规划问题,因为我们需要记录击败每个怪物后能够达到的最大怪物数量。我们可以使用一个字典dp来存储每个怪物被击败时能够达到的最大怪物数量。对于每个怪物,我们检查是否可以被小E的当前属性击败,如果可以,我们再检查前面所有能被当前怪物击败的怪物,看看是否通过击败当前怪物可以获得更大的怪物击败数。
分析
假设有4个怪物,每个怪物的血量和攻击力分别为:
- 怪物1: (h1, a1)
- 怪物2: (h2, a2)
- 怪物3: (h3, a3)
- 怪物4: (h4, a4)
并且小E的初始血量和攻击力为(H, A)。
- 首先检查小E是否能击败怪物1(即H > h1 且 A > a1)。
- 如果可以,我们初始化dp[1] = 1,表示击败怪物1后,击败了1个怪物。
- 然后检查怪物2,如果怪物2能被小E或更新后的小E击败(即当前怪物的血量和攻击力都严格大于前一个怪物的血量和攻击力,并且小于当前小E的血量和攻击力),我们更新dp[2] = dp[1] + 1,表示通过击败怪物2,可以达到的最大击败数为2。
- 依次类推,直到检查完所有怪物。
代码详解
python复制代码
def solution(n: int, H: int, A: int, h: list, a: list) -> int:
cnt = 0 # 记录最大击败怪物数
dp = {} # 动态规划字典,存储每个怪物被击败时能够达到的最大怪物数量
for i in range(n):
# 检查当前怪物是否能被小E击败
if H > h[i] and A > a[i]:
# 初始化dp[i]为1,表示击败当前怪物后,击败了1个怪物
dp[i] = 1
# 检查前面所有能被当前怪物击败的怪物
for j in range(i):
if h[j] < h[i] and a[j] < a[i]:
# 更新dp[i]为通过击败当前怪物能够达到的最大击败数
dp[i] = max(dp[i], dp[j] + 1)
# 更新最大击败怪物数
cnt = max(dp[i], cnt)
return cnt
知识总结
新知识点:
- 动态规划:动态规划是一种在数学、计算机科学和经济学中使用的,通过把原问题分解为相对简单的子问题的方式来求解复杂问题的方法。
- 字典在动态规划中的应用:字典可以用来存储中间结果,避免重复计算,提高算法效率。
理解:
动态规划的关键在于找到问题的子结构和最优子结构,即如何将原问题分解为子问题,以及如何利用子问题的解来构建原问题的解。在这个问题中,子问题就是击败每个怪物后能够达到的最大怪物数量。
学习建议:
- 多做动态规划的题目,熟悉不同类型的问题和解决方法。
- 理解动态规划的基本思想和步骤,掌握如何定义状态、状态转移方程和边界条件。
- 学会使用数据结构(如数组、字典等)来存储和更新中间结果。