BZOJ1801或洛谷2051 [AHOI2009]中国象棋
BZOJ原题链接
洛谷原题链接
这题挺难想状态的,刚看题感觉是状压,但数据\(100\)显然不可能。
注意到每行每列只能放\(0\sim 2\)个棋子,所以我们可以将这个写入状态。
设\(f[i][j][k]\)表示放了前\(i\)行,共有\(j\)列只放了一个棋子,共有\(k\)列放了两个棋子,而没有放棋子的列数则可以直接计算,即\(m - j - k\)。
然后分类讨论。
- 第\(i\)行不放
只有一种放法,直接由上一层转移:$$f[i][j][k] = f[i][j][k] + f[i - 1][j][k]$$
- 第\(i\)行放一个棋子
- 放在原本没有放棋子的列上,共\(m - (j - 1) - k\)种放法:$$f[i][j][k] = f[i][j][k] + f[i - 1][j - 1][k] \times (m - (j - 1) - k)$$
- 放在原本只有一个棋子的列上,共\(j + 1\)种放法:$$f[i][j][k] = f[i][j][k] + f[i - 1][j + 1][k - 1] \times (j + 1)$$
- 第\(i\)行放两个棋子
- 都放在原本没有放棋子的列上,共\(C_{m - (j - 2) - k} ^ 2\)种放法:$$f[i][j][k] = f[i][j][k] + f[i - 1][j - 2][k] \times C_{m - (j - 2) - k} ^ 2$$
- 一个放在空列,一个放在原本只有一个棋子的列上,共\(j \times (m - j - (k - 1))\)种放法:$$f[i][j][k] = f[i][j][k] + f[i - 1][j][k - 1] \times j \times (m - j - (k - 1))$$
- 都放在原本只有一个棋子的格子上,共\(C_{j + 2} ^ 2\)种放法:$$f[i][j][k] = f[i][j][k] + f[i - 1][j + 2][k - 2] \times C_{j + 2} ^ 2$$
初值\(f[0][0][0] = 1\),其它为\(0\)。
在\(DP\)过程中注意取模和边界问题。
最后答案就是\(\sum\limits_{i = 0} ^ m \sum \limits _{j = 0} ^ m f[n][i][j]\)。
#include<cstdio>
using namespace std;
const int N = 110;
const int mod = 9999973;
int f[N][N][N];
inline int re()
{
int x = 0;
char c = getchar();
bool p = 0;
for (; c < '0' || c > '9'; c = getchar())
p |= c == '-';
for (; c >= '0' && c <= '9'; c = getchar())
x = x * 10 + c - '0';
return p ? -x : x;
}
inline int C(int x)
{
return (1LL * x * (x - 1) >> 1) % mod;
}
int main()
{
int i, j, k, n, m, s = 0;
n = re();
m = re();
f[0][0][0] = 1;
for (i = 1; i <= n; i++)
for (j = 0; j <= m; j++)
for (k = 0; k + j <= m; k++)
{
f[i][j][k] = f[i - 1][j][k];
if (k)
{
f[i][j][k] = ((1LL * f[i - 1][j + 1][k - 1] * (j + 1) % mod) + f[i][j][k]) % mod;
f[i][j][k] = ((1LL * f[i - 1][j][k - 1] * j % mod * (m - j - k + 1) % mod) + f[i][j][k]) % mod;
}
if (j)
f[i][j][k] = ((1LL * f[i - 1][j - 1][k] * (m - j - k + 1) % mod) + f[i][j][k]) % mod;
if (j > 1)
f[i][j][k] = ((1LL * f[i - 1][j - 2][k] * C(m - j - k + 2) % mod) + f[i][j][k]) % mod;
if (k > 1)
f[i][j][k] = ((1LL * f[i - 1][j + 2][k - 2] * C(j + 2) % mod) + f[i][j][k]) % mod;
}
for (i = 0; i <= m; i++)
for (j = 0; j <= m; j++)
s = (1LL * s + f[n][i][j]) % mod;
printf("%d", s);
return 0;
}
BZOJ1801或洛谷2051 [AHOI2009]中国象棋的更多相关文章
- 洛谷.2051.[AHOI2009]中国象棋(DP)
题目链接 /* 每行每列不能超过2个棋子,求方案数 前面行对后面行的影响只有 放了0个.1个.2个 棋子的列数,与排列方式无关 所以设f[i][j][k]表示前i行,放了0个棋子的有j列,放了1个棋子 ...
- 洛谷2051 [AHOI2009]中国象棋
题目链接 题意概述:n行m列棋盘放若干个棋子每行每列最多两个求方案总数,答案对9999973取模. 可以比较容易看出这是个dp,设f[i][j][k]表示前i行j列放1个棋子k列放2个棋子的方案总数. ...
- [洛谷P2051] [AHOI2009]中国象棋
洛谷题目链接:[AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法 ...
- 洛谷 P2051 [AHOI2009]中国象棋 解题报告
P2051 [AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法. ...
- 洛谷 P2051 [AHOI2009]中国象棋 状态压缩思想DP
P2051 [AHOI2009]中国象棋 题意: 给定一个n*m的空棋盘,问合法放置任意多个炮有多少种情况.合法放置的意思是棋子炮不会相互打到. 思路: 这道题我们可以发现因为炮是隔一个棋子可以打出去 ...
- 洛谷 P2051 [AHOI2009]中国象棋
题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中国象棋中炮的行走方式是 ...
- 洛谷P2051 [AHOI2009]中国象棋(dp)
题面 luogu 题解 \(50pts:\)显然是\(3\)进制状压\(dp\) \(100pts:\) 一行一行地考虑 \(f[i][j][k]\)表示前\(i\)行,有\(j\)列放了一个,有\( ...
- 洛谷P2051 [AHOI2009] 中国象棋(状压dp)
题目简介 n*m的棋盘,对每行放炮,要求每行每列炮数<=2,求方案数%9999973 N,M<=100 题目分析 算法考虑 考虑到N,M范围较小,每一行状态只与前面的行状态有关,考虑状压D ...
- luogu 2051 [AHOI2009]中国象棋
luogu 2051 [AHOI2009]中国象棋 真是一道令人愉♂悦丧心并框的好题... 首先"没有一个炮可以攻击到另一个炮"有个充分条件就是没有三个炮在同一行或同一列.证明:显 ...
随机推荐
- Kubernetes K8s
1 Kubernetes入门及概念介绍 Kubernetes(K8s)是自动化容器操作的开源平台,这些操作包括部署,调度和节点集群间扩展.开源将Docker 看成Kubernetes内部使用的低级别组 ...
- SSM商城项目(三)
1. 学习计划 1.商品类目选择 2.图片上传 a) 图片服务器FastDFS b) 图片上传功能实现 3.富文本编辑器的使用KindEditor 2. 商品类目选择 2.1. 原型 2.2. 功能分 ...
- java+selenium自动化实践
git+java+selenium+testng +maven+idea 1.git之代码维护(下载.分支切换.上传) 下载命令 "git clone git@github.com:Luna ...
- 如何解决Android Studio解决DDMS真机/模拟器无法查看data目录问题
android app开发中,文件.SharedPreference或数据库默认保存在/data文件夹下,有时需要查看该文件夹下数据文件是否创建成功时,发现竟然打不开data目录: 具体解决方式如下: ...
- eclipce连接数据库增删改查
1.在mysql中新建一个名为course的数据库,并在其中新建一个course数据表,包含四个字段,id,name,teacher,classname如图(注意:将id设为自动递增,否则后面新增会出 ...
- Flux architecture
[Flux architecture] Flux is a pattern for managing data flow in your application. The most important ...
- Jmeter(三十九)获取响应结果中参数出现的次数(转载)
转载自 http://www.cnblogs.com/yangxia-test 在测试中,有时候会遇到要统计响应结果中某个参数出现了多少次,如果量级很大,一个一个数不太现实,下面讲一下实现自动打印出该 ...
- JMeter学习(二十九)自动化badboy脚本开发技术(转载)
转载自 http://www.cnblogs.com/yangxia-test 一般人用badboy都是使用它的录制功能,其它badboy还是一款自动化的工具,它可以实现检查点.参数化.迭代.并发.报 ...
- Pandas基本功能之算术运算、排序和排名
算术运算和数据对齐 Series和DataFrame中行运算和列运算有种特征叫做广播 在将对象相加时,如果存在不同的索引对,则结果的索引就是该索引对的并集.自动的数据对齐操作在不重叠的索引处引入了NA ...
- html中相对(relative),绝对(absolute)位置以及float的学习和使用案例 (转)
这几天着手于CSS的研究,研究的原因主要是工作需要,最近发现如果做前端仅仅会javascript很难尽善尽美,当然懂样式和html在一定程度上可以让我们更近一步. css较为简单,由于个人擅长编写代码 ...