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

 

posted @ 2020-12-06 16:50  朝暮不思  阅读(122)  评论(0编辑  收藏  举报