109 小M的光明之魂速通挑战 | 豆包MarsCode AI刷题

5 阅读3分钟

问题描述:

小M最近参加了一个名为《光明之魂》的速通比赛。在比赛中,玩家拥有N把武器以及M个Boss需要击败。规则如下:

  1. 每个Boss有一个唯一的类型编号,用一个正整数表示。
  2. 每把武器能够击败两种类型的Boss,但每把武器只能使用一次。
  3. 玩家必须按照给定的顺序逐个击杀Boss,不能跳过Boss顺序。

小M想知道,在不违反规则的前提下,他最多能够击败多少个Boss。

思路解析:

  1. 表示问题

    使用一个数组 boss 来表示需要按顺序击败的Boss的类型编号。 使用一个二维数组 array 来表示每把武器的能力,其中 array[i] = [type1, type2] 表示第 i 把武器能击败类型为 type1 和 type2 的Boss。 使用一个布尔数组 used 来跟踪每把武器是否已经被使用。

  2. DFS递归函数

    递归终止条件:如果 index 等于 boss 数组的长度,说明所有Boss都已经被考虑过,返回击败的Boss数量0。

    在每次递归调用中,我们检查当前武器列表中的每一把武器。 如果某把武器未被使用过,并且能击败当前的Boss,我们就标记它为已使用,并递归地考虑下一个Boss。 在递归返回后,我们需要撤销对当前武器的使用标记(回溯),以便在后续尝试中使用它。

  3. 跟踪最大击败数量

    在每次递归调用中,都需要跟踪并更新当前递归路径上能够击败的最大Boss数量。 这可以通过比较当前递归调用的结果(即当前路径上击败的Boss数量)与之前记录的最大数量来实现。

  4. 递归终止条件

    当我们处理完所有的Boss(即当前Boss索引等于Boss列表的长度)时,递归终止。 在这个点上,我们返回当前已击败的Boss数量作为结果。

解题步骤:

  1. 初始化

    读取输入的Boss类型和武器信息。 初始化一个表示武器使用情况的布尔数组 used,初始值全部为 False

  2. 调用DFS

    从第一个Boss开始,调用 dfs(boss, array, used, 0)。 递归终止条件:如果所有Boss都已击败

  3. 递归实现

    在递归函数中,遍历所有武器。 如果武器尚未使用且能击败当前Boss,则尝试使用这把武器(标记为已使用),并递归下一个Boss。 在递归返回后,撤销对当前武器的使用标记,并更新当前击败的最大Boss数量。

  4. 返回结果

    最终,DFS将返回能够击败的最大Boss数量。

代码示例:

def solution(n, m, boss, array):
    # Edit your code here

    used = [False] * n
    return dfs(boss,array,used,0)

def dfs(boss,array,used,index):
    if index == len(boss):
        return 0

    maxkill = 0

    for i in range(len(array)):
            if not used[i] and (array[i][0] == boss[index] or array[i][1] == boss[index]):
                used[i] = True
                kills = 1+ dfs(boss,array,used,index+ 1 )
                used[i] = False
                if kills >maxkill:
                    maxkill = kills
    return maxkill

个人思考:

1.这种方法虽然简单直接,但在处理大型问题时可能不够高效,由于我们需要尝试所有可能的武器组合,因此这个问题的时间复杂度是指数级的。对于较小的输入规模,这种方法是可行的,但对于较大的输入,可能需要使用更高效的算法。

2.在实际编码中,需要注意正确地处理回溯(即在递归返回后撤销对当前武器的使用标记),这是确保算法正确性的关键。