【题解】[USACO22FEB] Redistributing Gifts G
有个很奇妙的
首先题目等价于将给定图划分成若干个简单环,所以我们可以设计 DP 状态,
然后我们再合并环,
我一度认为
我们观察到由
那么我们更新一下状态,
但是这样
这样时间复杂度是
#define N 18
int n, a[N][N], e[N][N], bt[1 << N]; char ch[N + 5]; LL f[N][1 << N], g[1 << N];
int main() {
read(n);
rep(i, 0, n - 1){
rep(j, 0, n - 1)read(a[i][j]), a[i][j] --;
rep(j, 0, n - 1){
e[i][a[i][j]] = 1;
if(a[i][j] == i)break;
}
}
int w = (1 << n) - 1;
bt[0] = ~0; rp(i, w)bt[i] = bt[i >> 1] + 1;
g[0] = 1;
rep(s, 0, w){
int k = bt[s];
rep(i, 0, k){
if(e[i][k])g[s] += f[i][s];
rep(j, 0, k)if(!((s >> j) & 1) && e[i][j])
f[j][s | (1 << j)] += f[i][s];
}
rep(i, k + 1, n - 1)f[i][s | (1 << i)] += g[s];
}
int T; read(T);
while(T--){
scanf("%s", ch);
int s = 0;
rep(i, 0, n - 1)if(ch[i] == 'H')s |= 1 << i;
printf("%lld\n", g[s] * g[w ^ s]);
}
return 0;
}