题解 P2051 【[AHOI2009]中国象棋】
此题先用三进制的思路推下去,推成dp就是dp[i][j][k]表示放了前i行,有j列是有1个棋子,有k列有2个棋子
之后就很好理解了,分情况转移
上代码
#include<bits/stdc++.h>
using namespace std;
long long MOD=9999973;
long long n,m;
long long dp[110][110][110];
long long C(long long x)//C(x,2),求组合数
{
return x*(x-1)/2;
}
int main()
{
cin>>n>>m;
dp[0][0][0]=1;
for(int i=1;i<=n;i++)
{
for(int j=0;j<=m;j++)
{
for(int k=0;k<=m-j;k++)
{
dp[i][j][k]=dp[i-1][j][k];
if(k>=1)
dp[i][j][k]+=dp[i-1][j+1][k-1]*(j+1);
if(j>=1&&m-(j-1)-k>=0)
dp[i][j][k]+=dp[i-1][j-1][k]*(m-j-k+1);
if(j>=2)
dp[i][j][k]+=dp[i-1][j-2][k]*C(m-j-k+2);
if(k>=2)
dp[i][j][k]+=dp[i-1][j+2][k-2]*C(j+2);
if(k>=1&&m-j-(k-1)>=0)
dp[i][j][k]+=dp[i-1][j][k-1]*j*(m-j-k+1);
dp[i][j][k]%=MOD;
}
}
}
long long ans=0;
for (int i=0;i<=m;i++)
{
for (int j=0;j<=m-i;j++)
{
ans+=dp[n][i][j];
ans%=MOD;
}
}
cout<<ans;
}