求出数字1...n的全排列中完美排列的个数,完美排列是指排列的第(a_i)位为数字(b_i)(0<=i<m)
思路:f[i][j]表示排列长度为i时,数字填充状态为j时的不完美排列数
#include<cstdio>
#include<cstring>
#include<iostream>
typedef long long ll;
using namespace std;
const int N=17;
ll n,m,tot,p[N][N],f[N][1<<N],fac[N];
void init() {
fac[0]=1; for (int i=1;i<=N;i++) fac[i]=fac[i-1]*i;
}
int main() {
std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int Q; cin>>Q, init();
for (int q=0; q<Q; q++) {
cin>>n>>m, tot=1<<n, memset(p,0,sizeof p), memset(f,0,sizeof f);
for (int i=0; i<m; i++) {
int a,b; cin>>a>>b;
p[a-1][b-1]=1;
}
for (int i=0; i<n; i++) if (!p[0][i]) f[0][1<<i]=1;
for (int i=1; i<n; i++)
for (int j=0; j<tot; j++)
for (int k=0; k<n; k++) if ((j&(1<<k))==0 && !p[i][k]) //k是当前要填的数字,数字的第i位能填k(状态j没有填过k),且k不是"完美数字"是才是不完美
f[i][j|1<<k]+=f[i-1][j];
}
printf("Case %d: %lld
", q+1, fac[n]-f[n-1][tot-1]);
}
return 0;
}