1. 程式人生 > 實用技巧 >2020ICPC江西L WZB's Harem(狀壓dp)

2020ICPC江西L WZB's Harem(狀壓dp)

資料範圍不大,但是直接dfs顯然複雜度不正確,因此只能使用狀壓

用位運算表示前i位的數更新即可

#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; }
View Code