题目链接
摘自:
Dream_Maker_yangkai
链接
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
#define int long long
const int N = 110,mod = 9999973;
int f[N][N][N];
int C[N][N];
int n,m;
signed main()
{
cin>>n>>m;
for(int i=0;i<N;i++){
for(int j=0;j<=i;j++){
if(!j)C[i][j]=1;
else C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
}
}
if(n<m)swap(n,m);
f[0][0][0]=1;
//f[i][j][k]表示到第i行,有j列有1个数,k列有2个数的方案数。
for(int i=1;i<=n;i++)
{
for(int j=0;j<=m;j++)
{
for(int k=0;k<=m-j;k++)
{
int &v=f[i][j][k];
//什么也不选
v=f[i-1][j][k];
//第i行放1个 放到数量为0的列上
if(j)v=(v+f[i-1][j-1][k]*C[m-j-k+1][1]%mod)%mod;
//第i行放1个 放到数量为1的列上
if(k>=1&&j<=m-1)v=(v+f[i-1][j+1][k-1]*C[j+1][1]%mod)%mod;
//第i行放2个 分别放到两个数量为0的列上
if(j>=2)v=(v+f[i-1][j-2][k]*C[m-j-k+2][2]%mod)%mod;
//第i行放2个 分别放到一个数量为0和1的列上
if(j&&k)v=(v+f[i-1][j][k-1]*j%mod*(m-j-k+1)%mod)%mod;
//第i行放2个 分别放到两个数量为1的列上
if(k>=2&&j<=m-2)v=(v+f[i-1][j+2][k-2]*C[j+2][2]%mod)%mod;
}
}
}
int res=0;
for(int i=0;i<=m;i++)
for(int j=0;j<=m-i;j++)
res=(res+f[n][i][j])%mod;
cout<<res<<endl;
}