豆包109 小M的光明之魂速通挑战

127 阅读3分钟

问题描述

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

规则如下:

  1. 每个Boss对应唯一的类型编号。
  2. 每把武器能够击杀两种编号的boss且只能使用一次。
  3. 必须按照给定的顺序击杀Boss。

输入拥有的武器数量n 、需要击败的Boss数量m、Boss的顺序boss:长度为m的list、可以使用的武器array:一个长度为n的二维列表,每个元素为 [x, y],可以击败编号为 x 和 y 的Boss。

输出最多击败多少个boss。

使用方法

dfs(枚举选哪个)

算法思路

  1. 初始化数据结构

    • 使用一个HashMapmap)来存储每种类型的Boss对应的武器索引列表。键是Boss的类型编号,值是能够击败该Boss的武器索引列表。
    • 使用一个布尔数组vis来标记某个武器是否已经被使用。
  2. 构建Boss-武器关系图

    • 遍历二维数组array,对于每个武器,检查它能够击败的两个Boss类型编号(array[i][0]array[i][1]),并将对应的武器索引i添加到这两个Boss类型编号在map中的列表里。
  3. 深度优先搜索(DFS)

    • 定义一个dfs函数,它接受当前Boss的索引i作为参数,并返回从当前Boss开始,按照给定顺序最多能击败的Boss数量。
    • 如果i已经等于Boss列表boss的长度,说明已经考虑完所有Boss,返回0。
    • 如果当前Boss的类型编号在map中没有对应的武器列表,说明没有武器能击败这个Boss,返回0。
    • 对于当前Boss能够被击败的所有武器,尝试每一种武器,如果该武器(即对应的武器索引)没有被使用过(vis[tem]false),则标记为已使用,并递归调用dfs函数处理下一个Boss,同时更新最大击败Boss数量res
  4. 注意事项

    • 每次尝试使用一个武器后,需要将vis数组中对应的标记恢复,以便回溯到上一个状态,这是深度优先搜索中的“回溯”步骤。
    • dfs函数中的res = Math.max(dfs(boss, map, i + 1) + 1, res);是关键步骤,它意味着如果使用当前武器能够击败Boss,那么就尝试击败下一个Boss,并更新最大击败Boss数量。

代码展示

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Main {
    static boolean[] vis;

    public static int solution(int n, int m, int[] boss, int[][] array) {
        // 枚举选哪个
        Map<Integer, List<Integer>> map = new HashMap<>();
        for (int i = 0; i < array.length; i++) {
            if (!map.containsKey(array[i][0])) {
                var list = new ArrayList<Integer>();
                list.add(i);
                map.put(array[i][0], list);
            } else {
                var list = map.get(array[i][0]);
                list.add(i);
                map.put(array[i][0], list);
            }
            if (!map.containsKey(array[i][1])) {
                var list = new ArrayList<Integer>();
                list.add(i);
                map.put(array[i][1], list);
            } else {
                var list = map.get(array[i][1]);
                list.add(i);
                map.put(array[i][1], list);
            }
        }
        vis = new boolean[array.length];
        return dfs(boss, map, 0);
    }

    public static int dfs(int[] boss, Map<Integer, List<Integer>> map, int i) {
        if (i >= boss.length) {
            return 0;
        }
        if (map.get(boss[i]) == null) {
            return 0;
        }
        int res = 0;
        List<Integer> list = map.get(boss[i]);
        for (int t = 0; t < list.size(); t++) {
            int tem = list.get(t);
            if (!vis[tem]) {
                vis[tem] = true;
                res = Math.max(dfs(boss, map, i + 1) + 1, res);
                vis[tem] = false;
            }
        }
        return res;
    }

    public static void main(String[] args) {
        // Add your test cases here
        System.out.println(
                solution(3, 5, new int[] { 1, 2, 3, 4, 5 }, new int[][] { { 1, 2 }, { 3, 2 }, { 4, 5 } }) == 2);
        System.out.println(
                solution(3, 5, new int[] { 4, 3, 2, 1, 5 }, new int[][] { { 1, 2 }, { 3, 2 }, { 4, 5 } }) == 3);
        System.out.println(solution(4, 6, new int[] { 1, 2, 3, 4, 5, 6 },
                new int[][] { { 1, 2 }, { 2, 3 }, { 3, 4 }, { 5, 6 } }) == 3);
    }
}