• [AHOI2009]中国象棋


    题目大意:
      给你一个$n imes m(n,mle100)$的棋盘,问有多少种放法使得炮不会互相攻击。

    思路:
      动态规划。
      不难发现题目实际要求的是有多少种放法,使得每行、每列棋子不超过两个。用$f_{i,j,k}$表示前$i$行放了1个子的有$j$列,放了2个子的有$k$列。转移方程显然。

     1 #include<cstdio>
     2 #include<cctype>
     3 typedef long long int64;
     4 inline int getint() {
     5     register char ch;
     6     while(!isdigit(ch=getchar()));
     7     register int x=ch^'0';
     8     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
     9     return x;
    10 }
    11 const int N=101,mod=9999973;
    12 int f[N][N][N];
    13 int main() {
    14     const int n=getint(),m=getint();
    15     for(register int i=f[0][0][0]=1;i<=n;i++) {
    16         for(register int j=0;j<=m;j++) {
    17             for(register int k=0;j+k<=m;k++) {
    18                 f[i][j][k]=f[i-1][j][k];
    19                 if(j>=1) (f[i][j][k]+=(int64)f[i-1][j-1][k]*(m-j-k+1)%mod)%=mod;
    20                 if(k>=1&&j+1<=m) (f[i][j][k]+=(int64)f[i-1][j+1][k-1]*(j+1)%mod)%=mod;
    21                 if(j>=2) (f[i][j][k]+=(int64)f[i-1][j-2][k]*(m-j-k+2)*(m-j-k+1)/2%mod)%=mod;
    22                 if(k>=2&&j+2<=m) (f[i][j][k]+=(int64)f[i-1][j+2][k-2]*(j+2)*(j+1)/2%mod)%=mod;
    23                 if(j>=1&&k>=1) (f[i][j][k]+=(int64)f[i-1][j][k-1]*(m-j-k+1)*j%mod)%=mod;
    24             }
    25         }
    26     }
    27     int ans=0;
    28     for(register int j=0;j<=m;j++) {
    29         for(register int k=0;j+k<=m;k++) {
    30             ans=(ans+f[n][j][k])%mod;
    31         }
    32     }
    33     printf("%d
    ",ans);
    34     return 0;
    35 }
  • 相关阅读:
    排序——字符串怀疑人生
    广搜的变形+最短路思想 变色龙
    阿斯顿发发顺丰
    莫队暴力 一知半解
    P3384 【模板】树链剖分
    U74201 旅行计划 树上找链长度
    数据结构:线性表基本操作和简单程序
    数据结构:循环链表实现约瑟夫环
    Codeforces 215D. Hot Days(贪心)
    Codeforces 1080C- Masha and two friends
  • 原文地址:https://www.cnblogs.com/skylee03/p/8587681.html
Copyright © 2020-2023  润新知