• 【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
  • 相关阅读:
    怎么才能学好php
    MySQL: ON DUPLICATE KEY UPDATE 用法 避免重复插入数据
    RabbitMQ挂掉问题处理
    页面出现假死的问题
    memkeys 安装时遇到的问题及解决办法
    php 中的$argv与$argc
    PHPExcell单元格中某些时间格式的内容不能正确获得的处理办法
    php中的后期静态绑定("Late Static Binding")
    mybatis从零阅读(一)大纲
    windows 命令
  • 原文地址:https://www.cnblogs.com/shl-blog/p/11142611.html
Copyright © 2020-2023  润新知