码迷,mamicode.com
首页 > 其他好文 > 详细

P2051 [AHOI2009]中国象棋

时间:2018-02-10 11:20:37      阅读:183      评论:0      收藏:0      [点我收藏+]

标签:efi   难题   inf   100%   fine   ahoi2009   i++   思维   ret   

题目描述

这次小可可想解决的难题和中国象棋有关,在一个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]中国象棋

标签:efi   难题   inf   100%   fine   ahoi2009   i++   思维   ret   

原文地址:https://www.cnblogs.com/planche/p/8438108.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!