数据范围不大,但是直接dfs显然复杂度不正确,因此只能使用状压
用位运算表示前i位的数更新即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=3e5+10; const int mod=1e9+7; int a[100][100]; vector<int> num; int st[100]; ll f[25][(1<<20)]; int main(){ ios::sync_with_stdio(false); int n; int i,j; cin>>n; for(i=1;i<=n;i++){ for(j=1;j<=n;j++) cin>>a[i][j]; } for(i=0;i<n;i++){ if(a[1][i+1]) continue; f[1][1<<i]=1; num.push_back(1<<i); } for(i=2;i<=n;i++){ memset(st,0,sizeof st); vector<int> tmp; for(j=0;j<n;j++){ if(a[i][j+1]) continue; for(auto k:num){ if(k>>j&1) continue; f[i][k^(1<<j)]=(f[i][k^(1<<j)]+f[i-1][k])%mod; if(!st[k^(1<<j)]){ tmp.push_back((k^(1<<j))); st[k^(1<<j)]=1; } } } num=tmp; } ll x=1; for(i=2;i<=n;i++){ x=x*i%mod; } cout<<f[n][(1<<n)-1]*x%mod<<endl; return 0; }