题目解析(3) | 豆包MarsCode AI刷题

60 阅读3分钟

题目:小E的怪物挑战

题目描述:

小E在一个游戏中遇到了 n 个按顺序出现的怪物,每个怪物都有其特定的血量 hi​ 和攻击力 ai​。小E的初始血量为 H,攻击力为 A。游戏规则如下:

  1. 小E可以击败一个血量和攻击力都小于她当前属性的怪物。
  2. 对于第一个击败的怪物,需要满足其血量小于 H 且攻击力小于 A。
  3. 击败怪物后,小E会获得该怪物的属性值。
  4. 为了保持战斗节奏,要求击败的怪物序列中,后一个怪物的血量和攻击力都必须严格大于前一个怪物。

小E想知道,她最多能击败多少怪物。

测试样例:

样例1:

输入:n = 3, H = 4, A = 5, h = [1, 2, 3], a = [3, 2, 1]
输出:1

样例2:

输入:n = 5, H = 10, A = 10, h = [6, 9, 12, 4, 7], a = [8, 9, 10, 2, 5]
输出:2

样例3:

输入:n = 4, H = 20, A = 25, h = [10, 15, 18, 22], a = [12, 18, 20, 26]
输出:3

解题思路:

  1. 理解问题:我们需要找到一个最长的怪物序列,使得小E可以依次击败这些怪物,并且每个怪物的血量和攻击力都严格大于前一个怪物。

  2. 数据结构选择:使用动态规划(DP)来解决这个问题。定义一个DP数组 dp,其中 dp[i] 表示以第 i 个怪物结尾的最长可击败序列的长度。

  3. 算法步骤

    • 初始化:初始化一个 dp 数组,所有元素初始化为1(因为每个怪物至少可以击败自己)。
    • 双重循环:外层循环遍历每个怪物 i,对于每个怪物 i,再遍历所有之前的怪物 j,如果怪物 j 的血量和攻击力都小于怪物 i,则更新 dp[i]
    • 更新 dp[i]:如果怪物 j 可以被怪物 i 击败,则更新 dp[i] 为 dp[j] + 1 和当前 dp[i] 的最大值。
    • 返回最大值:最终返回 dp 数组中的最大值,即为最多可以击败的怪物数量。

代码实现:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int solution(int n, int H, int A, vector<int> h, vector<int> a) {
    // 初始化dp数组,所有元素初始化为1
    vector<int> dp(n, 1);
    
    // 遍历每个怪物
    for (int i = 0; i < n; ++i) {
        // 如果当前怪物可以被初始状态的小E击败
        if (h[i] < H && a[i] < A) {
            // 遍历所有之前的怪物
            for (int j = 0; j < i; ++j) {
                // 如果怪物j的血量和攻击力都小于怪物i
                if (h[j] < h[i] && a[j] < a[i]) {
                    // 更新dp[i]
                    dp[i] = max(dp[i], dp[j] + 1);
                }
            }
        }
    }
    
    // 找到dp数组中的最大值
    return *max_element(dp.begin(), dp.end());
}

int main() {
    cout << (solution(3, 4, 5, {1, 2, 3}, {3, 2, 1}) == 1) << endl;
    cout << (solution(5, 10, 10, {6, 9, 12, 4, 7}, {8, 9, 10, 2, 5}) == 2) << endl;
    cout << (solution(4, 20, 25, {10, 15, 18, 22}, {12, 18, 20, 26}) == 3) << endl;
    return 0;
}

总结:

  1. 动态规划的应用:本题通过动态规划的思想,定义了一个 dp 数组来记录以每个怪物结尾的最长可击败序列的长度。通过双重循环,逐步更新 dp 数组,最终找到最大值。
  2. 时间复杂度:该算法的时间复杂度为 O(n2),其中 n 是怪物的数量。对于每个怪物,我们都需要遍历所有之前的怪物,因此需要两层循环。
  3. 空间复杂度:空间复杂度为 O(n),因为我们使用了一个长度为 n 的 dp 数组来存储中间结果。