题目链接 [Ahoi2009]chess 中国象棋
设$f[i][j][k]$为前i行,$j$列放了1个棋子,$k$列放了2个棋子的方案数
分6种情况讨论,依次状态转移。
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) typedef long long LL;
const LL mod = ;
int n, m;
LL f[][][], ans = ; inline LL calc(LL x){ return x * (x - ) / ;} int main(){ scanf("%d%d", &n, &m);
f[][][] = ;
rep(i, , n){ rep(j, , m){ rep(k, , m - j){
f[i][j][k] = f[i - ][j][k];
if (j) f[i][j][k] += f[i - ][j - ][k] * (m - k - j + );
if (j < m && k) f[i][j][k] += f[i - ][j + ][k - ] * (j + );
if (j && k) f[i][j][k] += f[i - ][j][k -] * j * (m - j - k + );
if (j > ) f[i][j][k] += f[i - ][j - ][k] * calc(m - k - j + );
if (j <= m - && k > ) f[i][j][k] += f[i - ][j + ][k - ] * calc(j + );
f[i][j][k] %= mod;
} }
} rep(i, , m) rep(j, , m - i) (ans += f[n][i][j]) %= mod;
printf("%lld\n", ans);
return ;
}