P2051 [AHOI2009]中国象棋

Posted planche

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2051 [AHOI2009]中国象棋相关的知识,希望对你有一定的参考价值。

题目描述

这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法。大家肯定很清楚,在中国象棋中炮的行走方式是:一个炮攻击到另一个炮,当且仅当它们在同一行或同一列中,且它们之间恰好 有一个棋子。你也来和小可可一起锻炼一下思维吧!

输入输出格式

输入格式:

 

一行包含两个整数N,M,之间由一个空格隔开。

 

输出格式:

 

总共的方案数,由于该值可能很大,只需给出方案数模9999973的结果。

 

输入输出样例

输入样例#1: 复制
1 3
输出样例#1: 复制
7

说明

样例说明

除了3个格子里都塞满了炮以外,其它方案都是可行的,所以一共有2*2*2-1=7种方案。

数据范围

100%的数据中N和M均不超过100

50%的数据中N和M至少有一个数不超过8

30%的数据中N和M均不超过6

#include<bits/stdc++.h>
using namespace std;
#define maxn 110
typedef long long ll;
#define inf 0x3fffffff
#define mod 9999973

int n,m;
ll dp[maxn][maxn][maxn];

ll ans=0;

int main()
{
//    freopen("test.txt","r",stdin);
    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][k-1]*(m-j-k+1);
                if(j>=1)
                dp[i][j][k]+=dp[i-1][j-1][k+1]*(k+1);
                if(k>=2)
                dp[i][j][k]+=dp[i-1][j][k-2]*(m-j-k+2)*(m-j-k+1)/2;
                if(j>=1&&k>=1)
                dp[i][j][k]+=dp[i-1][j-1][k]*(m-j-k+1)*k;
                if(j>=2)
                dp[i][j][k]+=dp[i-1][j-2][k+2]*(k+2)*(k+1)/2;
                dp[i][j][k]%=mod;
            }

    for(int j=0; j<=m; j++)
    {
        for(int k=0; k<=m-j; k++)
            ans+=dp[n][j][k];
        ans%=mod;
    }
    cout<<ans;
    return 0;
}

 

以上是关于P2051 [AHOI2009]中国象棋的主要内容,如果未能解决你的问题,请参考以下文章

P2051 [AHOI2009]中国象棋

Luogu P2051 [AHOI2009]中国象棋(dp)

P2051 [AHOI2009] 中国象棋(dp)

P2051 [AHOI2009]中国象棋

P2051 [AHOI2009]中国象棋

P2051 [AHOI2009]中国象棋