• [AHOI2009]中国象棋


    AHOI

    题意

    求在$ncdot m​$的棋盘上摆放一些炮,使得任意两个炮不能互相攻击的方案数

    题解

    对于每一列,显然只能有0或1或2个炮,这是列中不能攻击的充要条件

    令$f_{i,j,k}$为考虑前i行,其中有j列有1个炮,k列有两个炮的方案数,这也意味着有$m-i-j$列没有放棋子

    分当前行放0或1或2个棋子讨论即可

    调试记录

    不必维护行的信息,在转移的时候行就是满足条件的

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30

    #include <algorithm>
    const int mo = 9999973;
    const int maxn = 105;
    using namespace std;
    int f[maxn][maxn][maxn], n, m;
    int (int x){
    return 1ll * x * (x - 1) / 2 % mo;
    }
    int main() 大专栏  [AHOI2009]中国象棋{
    scanf("%d%d", &n, &m);
    f[0][0][0] = 1;
    for (int i = 1; i <= n; i++){
    for (int j = 0; j <= m; j++)
    for (int k = 0; j + k <= m; k++){
    f[i][j][k] = f[i - 1][j][k];
    if (k > 0) f[i][j][k] = (f[i][j][k] + 1ll * f[i - 1][j + 1][k - 1] * (j + 1) % mo) % mo;
    if (j > 0) f[i][j][k] = (f[i][j][k] + 1ll * f[i - 1][j - 1][k] * (m - j - k + 1) % mo) % mo;
    if (k > 1) f[i][j][k] = (f[i][j][k] + 1ll * f[i - 1][j + 2][k - 2] * X(j + 2) % mo) % mo;
    if (k > 0) f[i][j][k] = (f[i][j][k] + 1ll * f[i - 1][j][k - 1] * j % mo * (m - j - k + 1) % mo) % mo;
    if (j > 1) f[i][j][k] = (f[i][j][k] + 1ll * f[i - 1][j - 2][k] * X(m - j - k + 2) % mo) % mo;
    }
    }
    int ans = 0;
    for (int j = 0; j <= m; j++)
    for (int k = 0; j + k <= m; k++)
    ans = (ans + f[n][j][k]) % mo;
    printf("%dn", ans);
    return 0;
    }
  • 相关阅读:
    使用vs2010编译 Python SIP PyQt4
    谷歌编程指南
    【转】微策略面经相关资料
    KMP 算法
    C++ 拷贝构造函数
    虚继承 虚表 定义一个不能被继承的类
    cache的工作原理
    背包问题
    【转】C/C++ 内存对齐
    【转】 Linux/Unix 进程间通信的各种方式及其比较
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12401974.html
Copyright © 2020-2023  润新知