zoukankan      html  css  js  c++  java
  • 【AHOI2009】中国象棋

    Description

    给定一个棋盘, 在棋盘上放入m个炮,使得炮两两之间不能攻击,求出方案数。

    Solution

    考虑设计一个dp,定义f[i][j][k]表示前i行、有j列放了一个炮、有k列放了两个炮的方案数。

    有一个显然的结论:如果方案合法,那么任何一行(列)的炮的数量最多为2。

    然后我们思考转移,假设当前状态为(i, j, k),我们有如下决策:

    当前这一行可以一个炮也不放

    如果一个炮都没放的列数量超过0,那么我们可以在这个位置上放一个炮

    如果放一个炮的列的数量超过0,那么我们可以在这个位置上放一个炮

    如果一个炮都没放的列数量超过1,那么我们可以在这个位置上放两个炮,方案数我们需要求一下组合数

    如果放一个炮的列的数量超过0,且不放炮的列的数量超过0,那么我们可以在这两个位置上各放一个炮

    如果放一个炮的列的数量超过1,那么我们可以在这里放两个炮,方案数我们需要求一下组合数

    综上,我们讨论出了状态转移,时间复杂度为O(nm^2);

    Code

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 int n, m;
     5 ll f[110][110][110];
     6 const int mod = 9999973;
     7 int calc(int x) {
     8     return x * (x - 1) / 2;
     9 }
    10 int main() {
    11     scanf("%d%d", &n, &m);
    12     f[0][0][0] = 1;
    13     for (register int i = 0; i < n; ++i) {
    14         for (register int j = 0; j <= m; ++j) {
    15             for (register int k = 0; k <= m; ++k) {
    16                 f[i + 1][j][k] = (f[i + 1][j][k] + f[i][j][k]) % mod;
    17                 if (m - j - k > 0) f[i + 1][j + 1][k] = (f[i + 1][j + 1][k] + f[i][j][k] * (m - j - k)) % mod;
    18                 if (j > 0) f[i + 1][j - 1][k + 1] = (f[i + 1][j - 1][k + 1] + f[i][j][k] * j) % mod;
    19                 if (j > 1) f[i + 1][j - 2][k + 2] = (f[i + 1][j - 2][k + 2] + f[i][j][k] * calc(j)) % mod;
    20                 if (j > 0 && m - j - k > 0) f[i + 1][j][k + 1] = (f[i + 1][j][k + 1] + f[i][j][k] * j * (m - j - k)) % mod;
    21                 if (m - j - k > 1) f[i + 1][j + 2][k] = (f[i + 2][j + 2][k] + f[i][j][k] * calc(m - j - k)) % mod;
    22             }
    23         }
    24     }
    25     ll ans = 0;
    26     for (register int i = 0; i <= m; ++i)
    27         for (register int j = 0; j + i <= m; ++j)
    28             ans = (ans + f[n][i][j]) % mod;
    29     printf("%lld
    ", ans % mod);
    30     return 0;
    31 }
    AC Code
  • 相关阅读:
    Locale IDs Assigned by Microsoft (zz)
    MFC 版本
    vs macro shortcuts
    关于strassen矩阵乘法的矩阵大小不是2^k的形式时,时间复杂度是否还是比朴素算法好的看法
    团体程序设计天梯赛 L2-016. 愿天下有情人都是失散多年的兄妹
    团体程序设计天梯赛-练习集 L1-031. 到底是不是太胖了
    团体程序设计天梯赛 L3-004. 肿瘤诊断
    团体程序设计天梯赛 L2-006. 树的遍历 L2-011. 玩转二叉树
    团体程序设计天梯赛 L1-011. A-B
    团体程序设计天梯赛 L1-010. 比较大小
  • 原文地址:https://www.cnblogs.com/shl-blog/p/11142611.html
Copyright © 2011-2022 走看看