分析
dp[i][s]
表示前
i
头牛,已经选了
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define pr(x) cout << #x << ": " << x << " "
#define pl(x) cout << #x << ": " << x << endl;
struct jiban
{
int n, m, k;
int dp[1 << 20], barn[22];
void fun() {
while (~scanf("%d%d", &n, &m)) {
memset(dp, 0, sizeof(dp));
dp[0] = 1;
for (int i = 1; i <= n; ++i) {
scanf("%d", &k);
for (int j = 0; j < k; ++j) scanf("%d", &barn[j]), barn[j]--;
for (int s = (1 << m) - 1; s >= 0; --s) {
dp[s] = 0;
for (int j = 0; j < k; ++j) {
if (s & (1 << barn[j])) {
dp[s] += dp[s & ~(1 << barn[j])];
}
}
}
}
int ans = 0;
for (int s = 0; s < 1 << m; ++s) ans += dp[s];
printf("%d\n", ans);
}
}
}ac;
int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif
ac.fun();
return 0;
}