[bzoj1801]chess 中国象棋
观察到摆放其实实在要求每行每列不能出现三个棋子
记f[k][i][j]为第k行时当前还有i列还能放两个棋子,j列还能放一个棋子的方案数
状态转移见代码
- 代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m;
ll mod=9999973;
ll f[110][110][110];
int main()
{
scanf("%d%d",&n,&m);
f[0][n][0]=1;
for(int i=1;i<=m;i++){
for(int j=0;j<=n;j++)
for(int k=0;k<=n;k++)if(j+k<=n)
f[i][j][k]=f[i-1][j][k];//不放
for(int j=0;j<=n;j++)
for(int k=0;k<=n;k++)if(j+k<=n){
f[i][j][k]+=f[i-1][j][k+1]*(k+1)%mod;
if(k)f[i][j][k]+=f[i-1][j+1][k-1]*(j+1)%mod;
//1个
}
for(int j=0;j<=n;j++)
for(int k=0;k<=n;k++)if(j+k<=n){
f[i][j][k]+=f[i-1][j][k+2]*(k+2)*(k+1)/2%mod;
f[i][j][k]+=f[i-1][j+1][k]*(j+1)*k%mod;
if(k>=2)f[i][j][k]+=f[i-1][j+2][k-2]*(j+2)*(j+1)/2%mod;
f[i][j][k]%=mod;
//2个
}
}
ll ans=0;
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)if(i+j<=n){
ans=(ans+f[m][i][j])%mod;
}
printf("%lld\n",(ans+mod)%mod);
}