Educational DP Contest O - Matching (状压dp)
O - Matching
原题链接:https://atcoder.jp/contests/dp/tasks/dp_o
题目大意:
有n个男人,n个女人,然后一男一女组合,其中一个二维矩阵a[i][j]记录第i个男人,与第j个女人能不能组合,求有多少种组合方式。
解题思路:
状压dp:用一个n为二进制的整数来表示n个人的选取状态,从0开始然后判断是否可选取第i位,可选取那位便加1,如到001,010,100,然后继续遍历。
代码:
1 #include <bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 #define debug(a) cout<<#a<<":"<<a<<endl;
5 const ll INF=0x3f3f3f3f;
6 const ll N=4e6+7;
7 const ll mod=1e9+7;
8 ll maxn,minn;
9 ll T,n,m;
10 ll mp[100][100];
11 ll dp[N];
12
13 int main(){
14 cin>>n;
15 for(ll i=0;i<n;i++){
16 for(ll j=0;j<n;j++){
17 scanf("%lld",&mp[i][j]);
18 }
19 }
20 dp[0]=1;
21 for(ll i=0;i<(1<<n);i++){
22 ll num=0;
23 for(ll j=0;j<n;j++){
24 if((i>>j)&1){
25 num++;
26 }
27 }
28 for(ll j=0;j<n;j++){
29 if(mp[num][j]==1&&((1<<j)^i)!=i){
30 dp[(1<<j)^i]=(dp[(1<<j)^i]+dp[i])%mod;
31 }
32 }
33 }
34 cout<<dp[(1<<n)-1]<<endl;
35 return 0;
36 }