【洛谷 P2051】 [AHOI2009]中国象棋(DP)
题目链接
首先想到状压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)的更多相关文章
- 洛谷P2051 [AHOI2009]中国象棋(dp)
题面 luogu 题解 \(50pts:\)显然是\(3\)进制状压\(dp\) \(100pts:\) 一行一行地考虑 \(f[i][j][k]\)表示前\(i\)行,有\(j\)列放了一个,有\( ...
- 洛谷 P2051 [AHOI2009]中国象棋 状态压缩思想DP
P2051 [AHOI2009]中国象棋 题意: 给定一个n*m的空棋盘,问合法放置任意多个炮有多少种情况.合法放置的意思是棋子炮不会相互打到. 思路: 这道题我们可以发现因为炮是隔一个棋子可以打出去 ...
- 洛谷 P2051 [AHOI2009]中国象棋 解题报告
P2051 [AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法. ...
- [洛谷P2051] [AHOI2009]中国象棋
洛谷题目链接:[AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法 ...
- 洛谷 P2051 [AHOI2009]中国象棋
题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中国象棋中炮的行走方式是 ...
- 洛谷P2051 [AHOI2009] 中国象棋(状压dp)
题目简介 n*m的棋盘,对每行放炮,要求每行每列炮数<=2,求方案数%9999973 N,M<=100 题目分析 算法考虑 考虑到N,M范围较小,每一行状态只与前面的行状态有关,考虑状压D ...
- 洛谷.2051.[AHOI2009]中国象棋(DP)
题目链接 /* 每行每列不能超过2个棋子,求方案数 前面行对后面行的影响只有 放了0个.1个.2个 棋子的列数,与排列方式无关 所以设f[i][j][k]表示前i行,放了0个棋子的有j列,放了1个棋子 ...
- Luogu P2051 [AHOI2009]中国象棋(dp)
P2051 [AHOI2009]中国象棋 题面 题目描述 这次小可可想解决的难题和中国象棋有关,在一个 \(N\) 行 \(M\) 列的棋盘上,让你放若干个炮(可以是 \(0\) 个),使得没有一个炮 ...
- [P2051 [AHOI2009]中国象棋] DP
https://www.luogu.org/problemnew/show/P2051 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一 ...
- BZOJ1801或洛谷2051 [AHOI2009]中国象棋
BZOJ原题链接 洛谷原题链接 这题挺难想状态的,刚看题感觉是状压,但数据\(100\)显然不可能. 注意到每行每列只能放\(0\sim 2\)个棋子,所以我们可以将这个写入状态. 设\(f[i][j ...
随机推荐
- Linux crontab命令:循环执行定时任务(详解版)
前面学习了 at 命令,此命令在指定的时间仅能执行一次任务,但在实际工作中,系统的定时任务一般是需要重复执行的.而 at 命令显然无法满足需求,这是就需要使用 crontab 命令来执行循环定时任务. ...
- Netty Socket编程
工程结构图 一.Socket服务端 1.创建MyServer 类 public class MyServer { public static void main(String[] args) thro ...
- Java_jdbc 基础笔记之十二 数据库连接 (beanutils )
public class BeanUtilsTest { /** * Java 类的属性: * 1.在JavaEE中,Java类的属性通过getter,setter来定义: get,set方法,去除 ...
- Gitlab修改用户密码
sudo gitlab-rails console production > user=User.where(name: "root").first > user.pa ...
- [转]curl 命令模拟 HTTP GET/POST 请求
在 Linux 操作系统上对后端程序进行测试的时候,需要进行模拟连接或者书写测试脚本 curl 访问百度,通过GET方法请求 命令格式: curl protocol://address:port/ur ...
- mysql 如何减少InnoDB关闭时间
原文连接: https://www.percona.com/blog/2009/04/15/how-to-decrease-innodb-shutdown-times/ 有时,运行InnoDB的MyS ...
- 通过cmd命令控制台关闭已经打开的端口号
通过cmd命令控制台关闭已经打开的端口号 在出现的窗口里面输入 netstat -ano, 就会出现所有的端口号, Local Address下面的是端口号, PID就是某程序占用的进程号, 这个进程 ...
- .Net Core控制台应用程序使用依赖注入、配置文件等
.Net Core作为一门新语言,资料实在是太少了,并且国内学习的人也不多,虽然性能还行也跨平台了但是生态圈不发展起来也不行 刚出来的时候用 .Net Core + Dapper + Mysql 弄了 ...
- PHP命令行参数
原文地址:http://php.swoole.com/wiki/PHP%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0 PHP命令行参数 目录 [隐藏] ...
- postgresql数据库中多个Schemas互相访问
背景: 用postgresql创建了一个数据库userDataBase,在这个数据库中创建了Schemas userA,Schemas userB,Schemas userC三个Schemas之后,给 ...