Atcoder Educational DP Contest O Matching

Description

n n 个男生和 n n 女生,给定一个 n × n n \times n 的 01 矩阵表示每对男女能否配对。求不同的配对方案数,每个人必须与一个异性配对。

1 n 21 1 \leq n \leq 21

Solution

数据范围告诉了我们状压 dp。

f i , m a s k f_{i,mask} 为前 i i 个男生配对的女生状态为 m a s k mask 的方案数,发现 i i 其实是 m a s k mask 1 1 的个数,这个可以用双下划线函数 __builtin_popcount 求。所以枚举 m a s k mask ,找一个女生与第 i i 个男生配对即可。

时间复杂度为 O ( 2 n × n ) O(2 ^n \times n)

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;
} 
发布了28 篇原创文章 · 获赞 38 · 访问量 494

猜你喜欢

转载自blog.csdn.net/qq_39984146/article/details/104223154