青训营X豆包MarsCode 技术训练营第三课-小E的怪物挑战| 豆包MarsCode AI刷题

101 阅读4分钟

题目描述
小E在一个游戏中按顺序遇到 n 个怪物,每个怪物有其特定的血量 h_i 和攻击力 a_i。小E初始血量为 H,攻击力为 A。游戏规则要求:

  1. 小E可以击败一个血量和攻击力都小于她当前属性的怪物。
  2. 第一个击败的怪物需要满足其血量小于 H 且攻击力小于 A
  3. 击败怪物后,小E会获得该怪物的属性值(即血量 h_i 和攻击力 a_i 会加到小E的当前属性上)。
  4. 击败的怪物序列中,后一个怪物的血量和攻击力都必须严格大于前一个怪物。

目标是找出小E最多能击败多少怪物。

思路
这是一个典型的动态规划问题,但需要考虑属性增长和怪物序列的严格递增性。我们可以使用动态规划数组 dp[i] 表示到第 i 个怪物时,小E最多能击败的怪物数量。然而,直接这样做会比较复杂,因为每次击败怪物后,小E的属性会改变。

一个更简单的方法是使用最长递增子序列(LIS) 的变种。我们可以将所有怪物按血量和攻击力的组合看作一个二维点 (h_i, a_i),并尝试找到满足条件的最长递增子序列。

具体步骤如下:

  1. 初始化一个空列表 monster_list 来存储满足初始条件(h_i < H 且 a_i < A)的怪物。
  2. 遍历所有怪物,对于每个怪物,如果它满足当前小E的属性要求,则将其加入 monster_list,并更新小E的属性为当前怪物属性加上之前的属性。
  3. 在 monster_list 中,按血量和攻击力进行排序,寻找最长递增子序列。这里可以使用动态规划或者二分查找来优化。

代码详解

def max_monsters(n, H, A, h, a):

    # Step 1: Filter monsters that can be initially defeated

    monster_list = [(h[i], a[i]) for i in range(n) if h[i] < H and a[i] < A]

    

    # If no monster can be defeated initially, return 0

    if not monster_list:

        return 0

    

    # Step 2: Sort the monster list by both health and attack in ascending order

    monster_list.sort()

    

    # Step 3: Find the longest increasing subsequence

    # We use a list to store the length of LIS ending at each index

    lis = [1] * len(monster_list)

    

    for i in range(1, len(monster_list)):

        for j in range(i):

            if monster_list[i] > monster_list[j]:

                lis[i] = max(lis[i], lis[j] + 1)

    

    # The answer is the maximum value in lis

    return max(lis)

 

# Example test cases

print(max_monsters(3, 4, 5, [1, 2, 3], [3, 2, 1]))  # Output: 1

print(max_monsters(5, 10, 10, [6, 9, 12, 4, 7], [8, 9, 10, 2, 5]))  # Output: 2

print(max_monsters(4, 20, 25, [10, 15, 18, 22], [12, 18, 20, 26]))  # Output: 3

### 知识总结

**新知识点**1.  **最长递增子序列(LIS)** :在给定序列中找到一个最长的子序列,使得子序列中的每个元素都严格大于前一个元素。
1.  **二维点的排序**:在处理多维数据时,可以通过排序和比较规则来简化问题。

**理解**:  
本题结合了动态规划和最长递增子序列的概念,要求我们在满足特定条件下寻找最优解。通过筛选初始可击败的怪物,并在排序后的列表中寻找最长递增子序列,可以有效地解决问题。

**学习建议**:  
建议首先掌握动态规划和最长递增子序列的基本概念,然后通过练习相关题目来加深理解。本题涉及多维数据的处理,因此理解二维点的排序和比较规则也很重要。

### 学习计划

**刷题计划**1.  **基础阶段**:每天练习5道动态规划和最长递增子序列的基础题目,巩固理论知识。
1.  **进阶阶段**:每天练习2道结合多维数据处理的题目,提升解决复杂问题的能力。
1.  **冲刺阶段**:每周至少完成一套完整的模拟题,检验学习成果。

**错题针对性学习**1.  对于每道错题,首先分析错误原因,并记录在错题本上。
1.  每周回顾错题本,针对薄弱环节进行强化练习。
1.  与同学或老师讨论错题,交流解题思路。

### 工具运用

**AI刷题功能**:  
利用豆包MarsCode AI的刷题功能,可以自动生成题目、提供解题思路和答案解析。这有助于我们快速找到自己的薄弱环节,并进行针对性练习。

**结合其他学习资源****在线课程**:结合在线算法课程,学习动态规划和最长递增子序列的深入理论。
  **编程社区**:参与编程社区的讨论,了解其他同学的解题思路和方法。


通过结合AI刷题功能和其他学习资源,我们可以更加高效地提升自己的算法能力。希望这些建议对大家有所帮助!