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 }

 

 
posted @ 2020-05-08 20:42  yya雨  阅读(741)  评论(0编辑  收藏  举报