题解 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;
}
posted @ 2019-02-03 22:06  G_A_TS  阅读(596)  评论(0)    收藏  举报