状态压缩裸题
https://atcoder.jp/contests/dp/tasks/dp_o

#include <bits/stdc++.h>
#include <iostream>
#include <string.h>
#include <math.h>

using namespace std;

const int mod = 1e9 + 7;
const int maxn = (1<<21) + 5;
int dp[30][maxn];
int a[30][30], b[30];
vector<int> can[30];
int main() {
    freopen("in.in", "r", stdin);
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cin >> a[i][j];
            b[i] += (1<<j)*a[i][j];
        }
    }
   for (int i = 1; i < (1<<n); i++) {
       if ((i | b[0]) == b[0]) {
           dp[0][i] = 1;
       }
   }
    for (int i = 1; i < n; i++) {
        for (int j = 0; j < n; j++) { //当前状态
            if (!a[i][j]) continue;
            int x = 1<<j;
            for (int k = 1; k < (1<<n); k++) { //前一个转态
                if((x & k) != 0 || !dp[i - 1][k]) continue;
                dp[i][x | k] += dp[i - 1][k];
                dp[i][x | k] %= mod;
            }
        }
    }
    cout << dp[n - 1][(1<<n) - 1] << endl;
    return 0;
}