题目链接

首先想到状压dp,但是\(n,m\)高达100,怎么压?

容易发现,每行每列最多两个象棋,否则就直接gg了。

一个巧妙的设置状态的方式是,只需要记录到当前行有多少列是放了1个炮和2个炮。

然后每一行有3种选择:不放、放1个、放2个。分情况转移就行了。

#include <cstdio>
const int MOD = 9999973;
const int MAXN = 110;
int n, m, ans;
long long f[MAXN][MAXN][MAXN];
int C(int x){ //C(x,2)
return x * (x - 1) / 2;
}
int main(){
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]) %= MOD; //不放
(f[i][j + 1][k] += f[i - 1][j][k] * (m - j - k)) %= MOD; //在没有棋子的列放1个
if(j) (f[i][j - 1][k + 1] += f[i - 1][j][k] * j) %= MOD; //在有棋子的列放1个
(f[i][j + 2][k] += f[i - 1][j][k] * C(m - j - k)) %= MOD; //在没有棋子的列放2个
(f[i][j][k + 1] += f[i - 1][j][k] * (m - j - k) * j) %= MOD; //一个放在有棋子的列,一个放啊没有棋子的列
if(j > 1) (f[i][j - 2][k + 2] += f[i - 1][j][k] * C(j)) %= MOD; //放2个在有棋子的列
}
for(int i = 0; i <= m; ++i)
for(int j = 0; i + j <= m; ++j)
(ans += f[n][i][j]) %= MOD;
printf("%d\n", ans);
return 0;
}

【洛谷 P2051】 [AHOI2009]中国象棋(DP)的更多相关文章

  1. 洛谷P2051 [AHOI2009]中国象棋(dp)

    题面 luogu 题解 \(50pts:\)显然是\(3\)进制状压\(dp\) \(100pts:\) 一行一行地考虑 \(f[i][j][k]\)表示前\(i\)行,有\(j\)列放了一个,有\( ...

  2. 洛谷 P2051 [AHOI2009]中国象棋 状态压缩思想DP

    P2051 [AHOI2009]中国象棋 题意: 给定一个n*m的空棋盘,问合法放置任意多个炮有多少种情况.合法放置的意思是棋子炮不会相互打到. 思路: 这道题我们可以发现因为炮是隔一个棋子可以打出去 ...

  3. 洛谷 P2051 [AHOI2009]中国象棋 解题报告

    P2051 [AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法. ...

  4. [洛谷P2051] [AHOI2009]中国象棋

    洛谷题目链接:[AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法 ...

  5. 洛谷 P2051 [AHOI2009]中国象棋

    题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中国象棋中炮的行走方式是 ...

  6. 洛谷P2051 [AHOI2009] 中国象棋(状压dp)

    题目简介 n*m的棋盘,对每行放炮,要求每行每列炮数<=2,求方案数%9999973 N,M<=100 题目分析 算法考虑 考虑到N,M范围较小,每一行状态只与前面的行状态有关,考虑状压D ...

  7. 洛谷.2051.[AHOI2009]中国象棋(DP)

    题目链接 /* 每行每列不能超过2个棋子,求方案数 前面行对后面行的影响只有 放了0个.1个.2个 棋子的列数,与排列方式无关 所以设f[i][j][k]表示前i行,放了0个棋子的有j列,放了1个棋子 ...

  8. Luogu P2051 [AHOI2009]中国象棋(dp)

    P2051 [AHOI2009]中国象棋 题面 题目描述 这次小可可想解决的难题和中国象棋有关,在一个 \(N\) 行 \(M\) 列的棋盘上,让你放若干个炮(可以是 \(0\) 个),使得没有一个炮 ...

  9. [P2051 [AHOI2009]中国象棋] DP

    https://www.luogu.org/problemnew/show/P2051 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一 ...

  10. BZOJ1801或洛谷2051 [AHOI2009]中国象棋

    BZOJ原题链接 洛谷原题链接 这题挺难想状态的,刚看题感觉是状压,但数据\(100\)显然不可能. 注意到每行每列只能放\(0\sim 2\)个棋子,所以我们可以将这个写入状态. 设\(f[i][j ...

随机推荐

  1. Linux crontab命令:循环执行定时任务(详解版)

    前面学习了 at 命令,此命令在指定的时间仅能执行一次任务,但在实际工作中,系统的定时任务一般是需要重复执行的.而 at 命令显然无法满足需求,这是就需要使用 crontab 命令来执行循环定时任务. ...

  2. Netty Socket编程

    工程结构图 一.Socket服务端 1.创建MyServer 类 public class MyServer { public static void main(String[] args) thro ...

  3. Java_jdbc 基础笔记之十二 数据库连接 (beanutils )

    public class BeanUtilsTest { /** * Java 类的属性: * 1.在JavaEE中,Java类的属性通过getter,setter来定义: get,set方法,去除 ...

  4. Gitlab修改用户密码

    sudo gitlab-rails console production > user=User.where(name: "root").first > user.pa ...

  5. [转]curl 命令模拟 HTTP GET/POST 请求

    在 Linux 操作系统上对后端程序进行测试的时候,需要进行模拟连接或者书写测试脚本 curl 访问百度,通过GET方法请求 命令格式: curl protocol://address:port/ur ...

  6. mysql 如何减少InnoDB关闭时间

    原文连接: https://www.percona.com/blog/2009/04/15/how-to-decrease-innodb-shutdown-times/ 有时,运行InnoDB的MyS ...

  7. 通过cmd命令控制台关闭已经打开的端口号

    通过cmd命令控制台关闭已经打开的端口号 在出现的窗口里面输入 netstat -ano, 就会出现所有的端口号, Local Address下面的是端口号, PID就是某程序占用的进程号, 这个进程 ...

  8. .Net Core控制台应用程序使用依赖注入、配置文件等

    .Net Core作为一门新语言,资料实在是太少了,并且国内学习的人也不多,虽然性能还行也跨平台了但是生态圈不发展起来也不行 刚出来的时候用 .Net Core + Dapper + Mysql 弄了 ...

  9. PHP命令行参数

    原文地址:http://php.swoole.com/wiki/PHP%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0   PHP命令行参数 目录 [隐藏]  ...

  10. postgresql数据库中多个Schemas互相访问

    背景: 用postgresql创建了一个数据库userDataBase,在这个数据库中创建了Schemas userA,Schemas userB,Schemas userC三个Schemas之后,给 ...