• BZOJ1801: [Ahoi2009]chess 中国象棋


    1801: [Ahoi2009]chess 中国象棋

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 765  Solved: 435
    [Submit][Status]

    Description

    在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮。 请问有多少种放置方法,中国像棋中炮的行走方式大家应该很清楚吧.

    Input

    一行包含两个整数N,M,中间用空格分开.

    Output

    输出所有的方案数,由于值比较大,输出其mod 9999973

    Sample Input

    1 3

    Sample Output

    7

    HINT

    除了在3个格子中都放满炮的的情况外,其它的都可以.

    100%的数据中N,M不超过100
    50%的数据中,N,M至少有一个数不超过8
    30%的数据中,N,M均不超过6

    Source

    Day2

    题解:

    Benz的题解:
    其实我觉得这题很好。Dp。
    50%的分数可以状态压缩拿到。
    因为棋盘上没有障碍,所以其实状态只跟有多少列放了1个棋子,多少列放了2个有关,
    而跟具体是哪几列无关。
    那么就可以不用状态压缩了。
    f[i][j][k]表示前i行,有j列放1个棋子,有k列放2个棋子的方案数。
    转移时枚举这一行放0 1 或 2个棋子即可。
    复杂度:O(n*m^2)。
    用int64存,每个状态算完后再取模。

    代码:

     1 #include<cstdio>
     2 
     3 #include<cstdlib>
     4 
     5 #include<cmath>
     6 
     7 #include<cstring>
     8 
     9 #include<algorithm>
    10 
    11 #include<iostream>
    12 
    13 #include<vector>
    14 
    15 #include<map>
    16 
    17 #include<set>
    18 
    19 #include<queue>
    20 
    21 #include<string>
    22 
    23 #define inf 1000000000
    24 
    25 #define maxn 105
    26 
    27 #define maxm 500+100
    28 
    29 #define eps 1e-10
    30 
    31 #define ll long long
    32 
    33 #define pa pair<int,int>
    34 
    35 #define for0(i,n) for(int i=0;i<=(n);i++)
    36 
    37 #define for1(i,n) for(int i=1;i<=(n);i++)
    38 
    39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
    40 #define mod 9999973
    41 
    42 using namespace std;
    43 
    44 inline int read()
    45 
    46 {
    47 
    48     int x=0,f=1;char ch=getchar();
    49 
    50     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    51 
    52     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    53 
    54     return x*f;
    55 
    56 }
    57 ll n,m,f[maxn][maxn][maxn];
    58 inline int c(int x)
    59 {
    60     return x*(x-1)/2;
    61 }    
    62 
    63 int main()
    64 
    65 {
    66 
    67     freopen("input.txt","r",stdin);
    68 
    69     freopen("output.txt","w",stdout);
    70 
    71     n=read();m=read();
    72     f[0][0][0]=1;
    73     for1(i,n)
    74      for0(j,m)
    75       for(int k=0;j+k<=m;k++)
    76       {
    77           f[i][j][k]=f[i-1][j][k];
    78           if(j>0)f[i][j][k]+=f[i-1][j-1][k]*(m-j-k+1);
    79           if(k>0)f[i][j][k]+=f[i-1][j+1][k-1]*(j+1);
    80           if(k>1)f[i][j][k]+=f[i-1][j+2][k-2]*c(j+2);
    81           if(k>0)f[i][j][k]+=f[i-1][j][k-1]*j*(m-j-k+1);
    82           if(j>1)f[i][j][k]+=f[i-1][j-2][k]*c(m-j-k+2);      
    83           if(f[i][j][k]>=mod)f[i][j][k]%=mod;     
    84       }
    85     ll ans=0;
    86     for0(i,m)
    87      for0(j,m)
    88       ans+=f[n][i][j],ans%=mod;
    89     printf("%lld
    ",ans);       
    90 
    91     return 0;
    92 
    93 }
    View Code

    ll.。。。

  • 相关阅读:
    有用工具
    Questions
    Verizon Wireless 4G LTE DROID
    测试的几点心得
    推荐书
    工作总结
    电脑故障排查检修积累
    Windows 8 下如何安装Framework 3.5
    空间域名的选择项
    自动化research
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/3964231.html
Copyright © 2020-2023  润新知