zoukankan      html  css  js  c++  java
  • [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



    然后我想到了压位dp,按3进制表示当前棋盘的状态,即某一列没有棋子,或者有一个,两个棋子,能过50分

    接着可以发现,棋子的顺序是无所谓的,并不需要准确知道当前棋盘的状态

    于是有了100分做法:dp[i][j][k]表示放了前i行,有j列是有1个棋子,有k列有两个棋子、



     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<cctype>
     5 #include<cstring>
     6 #define mod 9999973
     7 #define int long long
     8 #define R register
     9 using namespace std;
    10 inline  void in(int &x)
    11 {
    12     int f=1;x=0;char s=getchar();
    13     while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
    14     while(isdigit(s)){x=x*10+s-'0';s=getchar();}
    15     x*=f;
    16 }
    17 int n,m,ans;
    18 int f[108][108][108];
    19 inline int C(int x)
    20 {
    21     return ((x*(x-1))/2)%mod;
    22 }
    23 signed main()
    24 {
    25     in(n),in(m);
    26     f[0][0][0]=1;
    27     for(R int i=1;i<=n;i++)
    28     {
    29         for(R int j=0;j<=m;j++)
    30         {
    31             for(R int k=0;k<=m-j;k++)
    32             {
    33                 f[i][j][k]=f[i-1][j][k];
    34                 if(k>=1)(f[i][j][k]+=f[i-1][j+1][k-1]*(j+1));
    35                 if(j>=1)(f[i][j][k]+=f[i-1][j-1][k]*(m-j-k+1));
    36                 if(k>=2)(f[i][j][k]+=f[i-1][j+2][k-2]*(((j+2)*(j+1))/2));
    37                 if(k>=1)(f[i][j][k]+=f[i-1][j][k-1]*j*(m-j-k+1));
    38                 if(j>=2)(f[i][j][k]+=f[i-1][j-2][k]*C(m-j-k+2));
    39                 f[i][j][k]%=mod;
    40             }
    41         }
    42     }
    43     for(R int i=0;i<=m;i++)
    44         for(R int j=0;j<=m;j++)
    45             (ans+=f[n][i][j])%=mod;
    46     printf("%lld",(ans+mod)%mod);
    47 }
  • 相关阅读:
    VC++2012编程演练数据结构《25》线索二叉树
    VC++2012编程演练数据结构《26》最大堆二叉树
    VC++2012编程演练数据结构《19》散列文件
    VC++2012编程演练数据结构《21》二叉排序树
    VC++2012编程演练数据结构《23》二叉树排序
    VC++2012编程演练数据结构《22》常规排序算法
    VC++2012编程演练数据结构《27》最小堆二叉树
    VC++2012编程演练数据结构《20》索引文件
    自从来到了上海,开始工作以来就没怎么到博客园
    Graphics 单元中的类
  • 原文地址:https://www.cnblogs.com/zhangbuang/p/10356178.html
Copyright © 2011-2022 走看看