AHOI2009中国象棋
首先以行为阶段,根据象棋的规则,在同一行中,至多只能有两个炮,同理:在同一列中,至多只能有两个炮
思考一个可以覆盖整个状态空间的dp数组:
dp[i]表示到了第i行
接下来我们想:某列中的炮能否通过位运算求得
我们能够发现,可能我们目前在第i行,但是在某个j行的p列有一个炮,我们要知道第i行的第p列能否放置炮。但是j可能与i相差甚远,我们不能直接通过位运算得到,逐行枚举又会耗费大量不必要的时间。
那么我们就干脆将列的状态记录在数组里,我们想我们其实并不关心到第i行时哪一列有1个炮,哪一列有两个炮,我们只需要知道到第i行时,有多少列有1个炮,有多少列有两个炮,剩下的问题我们能够通过枚举状态解决
这样就有了dp数组:
dp[i][j][k]表示到第i行时,有j列有一个炮,k列有两个炮
假设第i行只放一个炮,那么放置的方法数累加(DP方程)就是:
1.这一个炮放在了原来没有炮的位置
dp[i][j][k] += dp[i - 1][j - 1][k] * (m - j - k)
2.这一个炮放在了原来有一个炮的位置
dp[i][j][k] += dp[i - 1][j + 1][k - 1] * j
假设第i行放置了两个炮
1.这一行两个炮都放在了原来没有炮的位置
dp[i][j][k] += dp[i - 1][j - 2][k] * (m - j - k) * (m - j - k - 1) / 2;
2.这一行一个炮放在了原来有一个炮的位置,一个炮放在了原来没有炮的位置
dp[i][j][k] += dp[i - 1][j][k - 1] * (m - j - k) * j
3.这一行的两个炮都放在了原来有一个炮的位置
dp[i][j][k] += dp[i - 1][j + 2][k - 2] * j * (j - 1) / 2;
假设第i行没有放炮
dp[i][j][k] += dp[i - 1][j][k]
=-=??好像没了?接着就是处理一下每种情况能够使用的限制条件
初态:dp[0][0][0] = 1;
末态:Σdp[n][i][j]
恩是的,这是我原本的思路,但我这么写后,不知道为什么就挂了。
挂了!样例都过不了!
于是我毅然决然的把有前驱推当前状态的写法改为了由当前状态推后继状态,然后就...A了.....
方程差别不大,不做修改,直接看代码吧...
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int p = ;
const int maxn = ;
ll f[maxn][maxn][maxn];
int n, m; inline int read() {
int x = , y = ;
char ch = getchar();
while(!isdigit(ch)) {
if(ch == '-') y = -;
ch = getchar();
}
while(isdigit(ch)) {
x = (x << ) + (x << ) + ch - '';
ch = getchar();
}
return x * y;
} inline int count(int k) {
return k * (k - ) / ;} int main() {
memset(f, , sizeof(f));
n = read(), m = read();
f[][][] = ;
for(int i = ; i < n; ++i)
for(int j = ; j <= m; ++j)
for(int k = ; k + j <= m; ++k)
if(f[i][j][k]) {
f[i + ][j][k] = (f[i][j][k] + f[i + ][j][k]) % p;
if(m - j - k >= ) f[i + ][j + ][k] = (f[i + ][j + ][k] + f[i][j][k] * (m - j - k)) % p;
if(j >= ) f[i + ][j - ][k + ] = (f[i + ][j - ][k + ] + f[i][j][k] * j) % p;
if(m - j - k >= ) f[i + ][j + ][k] = (f[i + ][j + ][k] + f[i][j][k] * count(m - j - k)) % p;
if(m - j - k >= && j >= ) f[i + ][j][k + ] = (f[i + ][j][k + ] + f[i][j][k] * (m - j - k) * j) % p;
if(j >= ) f[i + ][j - ][k + ] = (f[i + ][j - ][k + ] + f[i][j][k] * count(j)) % p;
f[i][j][k] %= p;
}
ll ans = ;
for(int i = ; i <= m; ++i)
for(int j = ; j + i <= m; ++j)
ans = (ans + f[n][i][j]) % p;
cout << ans << '\n';
return ;
}
AHOI2009中国象棋的更多相关文章
- 洛谷 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\) 个),使得没有一个炮 ...
- [Luogu P2051] [AHOI2009]中国象棋 (状压DP->网格DP)
题面 传送门:https://www.luogu.org/problemnew/show/P2051 Solution 看到这题,我们不妨先看一下数据范围 30pt:n,m<=6 显然搜索,直接 ...
- P2051 [AHOI2009]中国象棋
题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中国象棋中炮的行走方式是 ...
- [AHOI2009]中国象棋
题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中国象棋中炮的行走方式是 ...
- [P2051 [AHOI2009]中国象棋] DP
https://www.luogu.org/problemnew/show/P2051 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一 ...
- BZOJ1801:[AHOI2009]中国象棋——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1801 https://www.luogu.org/problemnew/show/P2051 这次小 ...
随机推荐
- 详解npm的模块安装机制
详解npm的模块安装机制 依赖树表面的逻辑结构与依赖树真实的物理结构 依赖树表面的逻辑结构与依赖树真实的物理结构并不一定相同! 这里要先提到两个命令:tree -d(linux)和npm ls(npm ...
- BZOJ1876 [SDOI2009]SuperGCD 【高精 + GCD优化】
题目 Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的GCD(最大公约 数)!因此他经常和别人比 赛计算GCD.有一天Sheng bill很嚣张地找到了你,并要求和你比 赛,但 ...
- 洛谷 P2501 [HAOI2006]数字序列 解题报告
P2501 [HAOI2006]数字序列 题目描述 现在我们有一个长度为n的整数序列A.但是它太不好看了,于是我们希望把它变成一个单调严格上升的序列.但是不希望改变过多的数,也不希望改变的幅度太大. ...
- bzoj 4836 [Lydsy1704月赛]二元运算 分治FFT+生成函数
[Lydsy1704月赛]二元运算 Time Limit: 8 Sec Memory Limit: 128 MBSubmit: 577 Solved: 201[Submit][Status][Di ...
- iOS 全局变量设置的几种方式~
在iOS开发过程中关于全局变量的几个方法 1. 在APPDelegate中声明并初始化全局变量.AppDelegate可以在整个应用程序中调用,在其他页面中可以使用代码段获取AppDelegate的全 ...
- 转:Spring AOP详解
转:Spring AOP详解 一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址: ...
- mybatis的一些特殊符号标识(大于,小于,等于,不等于)
特殊字符 替代符号(红色基本为常用的) & & < < > > ...
- JVM内存模型 三
本文章节: 1.JMM简介 2.堆和栈 3.本机内存 4.防止内存泄漏 1.JMM简介 i.内存模型概述 Java平台自动集成了线程以及多处理器技术,这种集成程度比Java以前诞生的计算机语言要厉 ...
- 汕头市队赛 SRM 06 C 秀恩爱
C 秀恩爱 SRM 06 背景&&描述 KPM坐在直升机上俯瞰小渔村景象. 渔村可看作二维平面,密密麻麻地到处都是单身狗,KPM当前所在坐标为(sx,s ...
- unicode字符串解码显示
# encoding: utf-8 ''' unicode字符串解码显示 ''' import sys reload(sys) sys.setdefaultencoding('utf-8') a = ...