问题描述
小M最近参加了一个名为《光明之魂》的速通比赛。在比赛中,玩家拥有N把武器以及M个Boss需要击败。规则如下:
- 每个Boss有一个唯一的类型编号,用一个正整数表示。
- 每把武器能够击败两种类型的Boss,但每把武器只能使用一次。
- 玩家必须按照给定的顺序逐个击杀Boss,不能跳过Boss顺序。
小M想知道,在不违反规则的前提下,他最多能够击败多少个Boss。
输入变量说明:
n表示拥有的武器数量。m表示需要击败的Boss数量。boss是一个长度为m的列表,表示玩家必须按照顺序击杀的Boss的类型。array是一个长度为n的二维列表,每个元素为[x, y],表示对应的武器可以击败类型为x和y的Boss。
测试样例
-
样例1
输入:
n = 3 ,m = 5 ,boss = [1, 2, 3, 4, 5] ,array = [[1, 2], [3, 2], [4, 5]]
输出:2 -
样例2
输入:
n = 3 ,m = 5 ,boss = [4, 3, 2, 1, 5] ,array = [[1, 2], [3, 2], [4, 5]]
输出:3 -
样例3
输入:
n = 4 ,m = 6 ,boss = [1, 2, 3, 4, 5, 6] ,array = [[1, 2], [2, 3], [3, 4], [5, 6]]
输出:3
解题思路
- 明确使用深度优先(dfs)。由于题目明确要求每把武器只能使用一次,所以得使用某个数据结构来保存每把武器的使用情况
- 使用dfs时注意递归的出口,即遍历完所有boss,或在某一boss无法继续递归时,应结束
- boss只能按顺序击杀所以boss数组不能交换顺序
代码实现
第一步
选取数据结构,表示武器是否使用。可以采用数组,数组第i位代表第i把武器的使用情况,0代表已经使用1代表未使用。我这里采用的map,key是武器的序号,map为bool类型,true代表已使用,false代表未使用。res定义为结果变量。
s := map[int]bool{}
res := 0
第二步
编写dfs递归函数,首先idx表示为当前boss的序号。当该序号等于boss个数时结束递归,同时该序号也是可以击杀的boss数量,所以当idx大于res时,需将idx的值赋予res。遍历每一把武器,使用当前武器击杀boss的前提为,当前武器未使用并且该武器可以击杀当前boss。 如果满足条件,则将该武器状态改为已使用,进行下一个boss的递归,递归完当前武器需要将该武器状态设置为未使用。尝试不选择当前武器,是否还存在其它武器可以击杀当前boss。
dfs = func(idx int) {
if idx > res {
res = idx
}
if idx == m {
return
}
for i := 0; i < n; i++ {
if !s[i] && (array[i][0] == boss[idx] || array[i][1] == boss[idx]) {
s[i] = true
dfs(idx + 1)
s[i] = false
}
}
}
第三步
调用dfs函数,返回res结果
dfs(0)
return res