【简●解】[AHOI2009]中国象棋
【题目大意】
叫你在\(n×m\)的棋盘上放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,问有多少种放置方法。
【关键词】
- \(DP\)
- 分类讨论
- 乘法和加法原理
【分析】
仔细观察就会发现,棋盘中每行,每列只有放\(0\),\(1\),\(2\)个三种方案。如果我们把状态量设为列,那么知道任意两种方案的列数,即可用总列数减去它得到另一种方案的列数。
我们设状态方程:\(f[i][j][k]\),表示的是前\(i\)行,其中\(j\)列有\(1\)个棋子,\(k\)列有\(2\)个棋子的总方案数。
那么对于行的转移,我们有三种情况。
- 在第\(i\)行不放棋子。
- 在第\(i\)行放\(1\)个棋子。
- 在第\(i\)行放\(2\)个棋子。
不放棋子,即\(f[i][j][k]=f[i-1][j][k]\)。
放\(1\)个棋子,又分两种情况:
- 放在有\(1\)个棋子的列上,\(j+1\)列都可以放。即\(f[i][j][k]+=f[i-1][j+1][k-1]*(j+1)\)。
- 放在没有棋子的列上,\(m-(j-1)-k\)列都可放。即\(f[i][j][k]+=f[i-1][j-1][k]*(m-j-k+1)\)
放\(2\)个棋子,分三种情况:
- \(2\)个都放在没有棋子的列上。即\(f[i][j][k]+=f[i-1][j-2][k]*C_{m-(j-2)-k}^{2}\)。
- \(2\)个都放在有\(1\)个棋子的列上。即\(f[i][j][k]+=f[i-1][j+2][k-2]*C_{j+2}^2\)。
- \(1\)个放在没有棋子的列上,另一个放在有\(1\)个棋子的列上。即\(f[i][j][k]+=f[i-1][j][k-1]*(m-j-k+1)\)。
然后就可以\(A\)掉了,哦,记得开\(long long\)。。。
【Code】
#pragma GCC optimize("O3")
#pragma GCC optimize("O2")
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define ll long long
#define R register
using namespace std;
const int MAX = 100 + 5;
const int mod = 9999973;
inline int read(){
int f = 1, x = 0;char ch;
do { ch = getchar(); if (ch == '-') f = -1; } while (ch < '0'||ch>'9');
do {x = x*10+ch-'0'; ch = getchar(); } while (ch >= '0' && ch <= '9');
return f*x;
}
inline ll c(ll x) {
return (x * (x - 1) / 2) % mod;
}
int n, m;
ll f[MAX][MAX][MAX], ans;
int main(){
n = read(), m = read();
f[0][0][0] = 1;
for (R int i = 1;i <= n; ++i) {
for (R int j = 0;j <= m; ++j) {
for (R int k = 0;k <= m - j; ++k) {
f[i][j][k] = f[i-1][j][k];
if (k > 0) {
f[i][j][k] += (f[i-1][j+1][k-1] * (j+1)) % mod;
f[i][j][k] %= mod;
f[i][j][k] += (f[i-1][j][k-1] * j * (m-j-k+1)) %mod;
f[i][j][k] %= mod;
}
if (j > 0) {
f[i][j][k] += (f[i-1][j-1][k] * (m-j-k+1)) %mod;
f[i][j][k] %= mod;
}
if (k > 1) {
f[i][j][k] += (f[i-1][j+2][k-2] * c(j+2)) % mod;
f[i][j][k] %= mod;
}
if (j > 1) {
f[i][j][k] += (f[i-1][j-2][k] * c(m-j-k+2)) % mod;
f[i][j][k] %= mod;
}
}
}
}
for (R int i = 0;i <= m; ++i) {
for (R int j = 0;j <= m; ++j) {
ans += f[n][i][j];
ans %= mod;
}
}
printf("%lld", (ans + mod) % mod);
return 0;
}
【简●解】[AHOI2009]中国象棋的更多相关文章
- [Luogu P2051] [AHOI2009]中国象棋 (状压DP->网格DP)
题面 传送门:https://www.luogu.org/problemnew/show/P2051 Solution 看到这题,我们不妨先看一下数据范围 30pt:n,m<=6 显然搜索,直接 ...
- 洛谷 P2051 [AHOI2009]中国象棋 解题报告
P2051 [AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法. ...
- luogu 2051 [AHOI2009]中国象棋
luogu 2051 [AHOI2009]中国象棋 真是一道令人愉♂悦丧心并框的好题... 首先"没有一个炮可以攻击到另一个炮"有个充分条件就是没有三个炮在同一行或同一列.证明:显 ...
- [洛谷P2051] [AHOI2009]中国象棋
洛谷题目链接:[AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法 ...
- 洛谷 P2051 [AHOI2009]中国象棋 状态压缩思想DP
P2051 [AHOI2009]中国象棋 题意: 给定一个n*m的空棋盘,问合法放置任意多个炮有多少种情况.合法放置的意思是棋子炮不会相互打到. 思路: 这道题我们可以发现因为炮是隔一个棋子可以打出去 ...
- Luogu P2051 [AHOI2009]中国象棋(dp)
P2051 [AHOI2009]中国象棋 题面 题目描述 这次小可可想解决的难题和中国象棋有关,在一个 \(N\) 行 \(M\) 列的棋盘上,让你放若干个炮(可以是 \(0\) 个),使得没有一个炮 ...
- BZOJ1801:[AHOI2009]中国象棋——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1801 https://www.luogu.org/problemnew/show/P2051 这次小 ...
- DP【p2051(bzoj 1801)】 [AHOI2009]中国象棋.
题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中国象棋中炮的行走方式是 ...
- LG_2051_[AHOI2009]中国象棋
题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中国象棋中炮的行走方式是 ...
- P2051 [AHOI2009]中国象棋
题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中国象棋中炮的行走方式是 ...
随机推荐
- Android笔记---常用控件以及用法
这篇文章主要记录下Android的常用控件以及使用的方法,Android 给我们提供了大量的UI控件,合理地使用这些控件就可以非常轻松地编写出相当不错的界面,这些是Android学习的基础,没有什么业 ...
- 瞎比比系列---1st
A - 项目管理HDU4858 /* 题意: 这个项目有n个节点, 两个节点间可能有多条边,不过一条边的两端必然是不同的节点. 0的时候:接下来两个数u v表示给项目u的能量值加上v: 1的时候: 这 ...
- 拓扑排序+DFS(POJ1270)
[日后练手](非解题) 拓扑排序+DFS(POJ1270) #include<stdio.h> #include<iostream> #include<cstdio> ...
- bzoj 1090: [SCOI2003]字符串折叠【区间dp】
设f[i][j]为区间(i,j)的最短长度,然后转移的话一个是f[i][j]=min(j-i+1,f[i][k]+f[k+1][j]),还有就是把(k+1,j)合并到(i,k)上,需要判断一下字符串相 ...
- MySQL 错误码对照
1005:创建表失败 1006:创建数据库失败 1007:数据库已存在,创建数据库失败 1008:数据库不存在,删除数据库失败 1009:不能删除数据库文件导致删除数据库失败 1010:不能删除数据目 ...
- 百度编辑器ueditor插件的基本使用
注意:该插件是基于tpframe开发,请在tpframe框架上使用 插件下载地址:https://pan.baidu.com/s/1MOJbd1goQC0Bn5-7HcIdKA 插件下载下来后解压到a ...
- c++ 优先级大全
重置优先级
- AtCoder Regular Contest 083 E - Bichrome Tree
题目传送门:https://arc083.contest.atcoder.jp/tasks/arc083_c 题目大意: 给定一棵树,你可以给这些点任意黑白染色,并且赋上权值,现给定一个序列\(X_i ...
- Hdu 5446 Unknown Treasure (2015 ACM/ICPC Asia Regional Changchun Online Lucas定理 + 中国剩余定理)
题目链接: Hdu 5446 Unknown Treasure 题目描述: 就是有n个苹果,要选出来m个,问有多少种选法?还有k个素数,p1,p2,p3,...pk,结果对lcm(p1,p2,p3.. ...
- go获取当前执行的位置程序
func getCurrentPath() string { _, filename, _, ok := runtime.Caller(1) var cwdPath string if ok { cw ...