Description
有 个男生和 女生,给定一个 的 01 矩阵表示每对男女能否配对。求不同的配对方案数,每个人必须与一个异性配对。
。
Solution
数据范围告诉了我们状压 dp。
令 为前 个男生配对的女生状态为 的方案数,发现 其实是 中 的个数,这个可以用双下划线函数 __builtin_popcount 求。所以枚举 ,找一个女生与第 个男生配对即可。
时间复杂度为 。
Code
#include <bits/stdc++.h>
using namespace std;
const int N = 21 + 5;
int n, a[N][N], f[1 << N], p = 1e9 + 7;
int main() {
int n; scanf("%d", &n);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
scanf("%d", &a[i][j]);
f[0] = 1;
for (int mask = 0; mask < (1 << n); mask++) {
int i = __builtin_popcount(mask);
for (int j = 1; j <= n; j++) {
if (mask & (1 << (j - 1)) && a[i][j])
f[mask] = (f[mask] + f[mask ^ (1 << (j - 1))]) % p;
}
}
printf("%d\n", f[(1 << n) - 1]);
return 0;
}