LOL选英雄排列组合

小明周六终于完成了他的作ye,于是他决定在周末约上好朋友打一场LOL的比赛,他叫上了几个人一起玩游戏(不超过9人,加上他自己不超过10人)。

游戏开始前大家都要选英雄角色并且不能选择相同的角色也就是游戏里不允许出现两个相同的英雄角色。但是大家玩的时间都不是太久,游戏有m个英雄角色,每个人拥有一定数量的角色,可能有些角色有些人没有。现在喜欢计数的小明想要计算,这一局游戏里有多少种英雄排列。即使两种排列中英雄的种类相同,只要有有一个英雄的召唤师不同则会认定不同的排列。(本题和真实游戏有差别,具体标准请仔细理解题意。)
输入描述:
第一行两个整数n和m,代表这局游戏有n个人,游戏总共有m个不同的英雄。(1 <=n <= 10, 1 <= m <= 150)

下面n行,第i行第一个数字k代表第i个人拥有的英雄角色数量,后面跟着k个数字p1....pk代表英雄种类。 (保证英雄种类不重复)
(1 <= k <= m, 1 <=pj <=m)

输出描述:
输出有多少种英雄组合方式。由于答案太大请%998244353 。
示例1
输入
10 10
3 1 2 3
3 1 2 3
4 1 2 3 4
1 4
1 5
1 6
1 7
1 8
1 9
1 10
输出
6
说明
前三个人可以在1、2、3三种英雄中任选一种(因为3号选手如果选了4号英雄,则4号选手就无法选出英雄也就无法开始一场游戏),总共有6种英雄排列,而后面7个人选出的英雄排列只能是4,5,6,7,8,9,10,所以一共有6种不同的英雄组合方式。

img

回溯暴力解,但超时,卡好久了,没其他思路,本人菜菜,唠唠
import java.util.HashSet;

import java.util.Scanner;

public class Main {

static Scanner input = new Scanner(System.in);

static int n = input.nextInt();

static int m = input.nextInt();

static int[][] k = new int[n][m];

static int[] x = new int[n];

static int []k2 = new int[n];

static int []right = new int[n - 1];

static int count = 0;

public static boolean judge(int []k2, int index){

    HashSet<Integer> hashSet = new HashSet<>();

    int []arr = new int[index];

    if(index != n){

        for (int i = 0; i < index; i++){

            arr[i] = k2[i];

        }

        k2 = arr;

    }

    for (int j : k2) {

        hashSet.add(j);

    }

    return hashSet.size() == k2.length;

}

public static void heroCount(int i, int j){

    //System.out.println();

    if (i == 0 && j >= x[0]){

        System.out.println((count % 998244353));

        System.exit(0);

    }

    for (int index = n - 2; index > 0; index--){

        if (right[index] == x[index]){

            right[index] = 0;

            right[index - 1]++;

            heroCount(index - 1, right[index - 1]);

        }

    }

    for (int index = 0; index < n - 1; index++){

        //System.out.print(index +","+ right[index] +"\t");

        k2[index] = k[index][right[index]];

        if (!judge(k2, (index + 1)) ){

            right[index]++;      

            heroCount(index, right[index]);

        }

    }

    for (int downR = 0; downR < x[n -1]; downR++){

        //System.out.print((n-1) +","+ downR +"\t");

        k2[n - 1] = k[n - 1][downR];

        if (judge(k2, n)){

            count++;

            //System.out.println("count" + count);

        }

    }

    ++right[n - 2];

    heroCount(0, right[0]);

}

public static void main(String[] args) {

    for (int i = 0; i < n; i++) {

        x[i] = input.nextInt();

        for (int j = 0; j < x[i]; j++) {

            k[i][j] = input.nextInt();

        }

    }

    heroCount(0, 0);

}

}