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
  • 相关阅读:
    Flink Task 并行度
    flink笔记(三) flink架构及运行方式
    Flink笔记(二) DataStream Operator(数据流操作)
    poj 1463 Strategic game
    2014年3月29日小记
    AC自动机学习
    hdu 1028 Ignatius and the Princess III
    hdu 1542 Atlantis
    hdu 1575 Tr A
    hdu 4193 Non-negative Partial Sums
  • 原文地址:https://www.cnblogs.com/shl-blog/p/11142611.html
Copyright © 2011-2022 走看看