AHOI 2009 中国象棋
题面
题目描述
这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法。大家肯定很清楚,在中国象棋中炮的行走方式是:一个炮攻击到另一个炮,当且仅当它们在同一行或同一列中,且它们之间恰好 有一个棋子。你也来和小可可一起锻炼一下思维吧!
输入输出格式
输入格式:
一行包含两个整数N,M,之间由一个空格隔开。
输出格式:
总共的方案数,由于该值可能很大,只需给出方案数模9999973的结果。
输入输出样例
输入样例#1:
1 3
输出样例#1:
7
说明
样例说明
除了3个格子里都塞满了炮以外,其它方案都是可行的,所以一共有222-1=7种方案。
数据范围
100%的数据中N和M均不超过100
50%的数据中N和M至少有一个数不超过8
30%的数据中N和M均不超过6
Solution
乍看到这题, 真的没什么思路.
找到的比较靠谱的解法是这样的: 我们从上往下一行一行放置棋子, 用f[i][j][k]表示在前\(i\)行中, \(j\)列上有\(1\)个棋子, \(k\)列上有\(2\)个棋子的合法方案数. 考虑怎么转移: 开始时我考虑的是递归式, 发现式子的形式非常复杂, 有许多细节需要考虑, 因此改为递推式.
考虑在已经放置好的前\(i\)列的基础上, 在第\(i + 1\)列上放棋子. 我们可以在这一行上放\(0\)或\(1\)或\(2\)颗棋子, 并且要求这些棋子所在的列原来最多只能有\(1\)颗棋子. 暴力转移即可. 时间复杂度: \(O(nm^2)\).
#include <cstdio>
#include <cstring>
typedef long long LL;
const int N = 100, M = 100, MOD = 9999973;
int n, m;
int f[N + 7][M + 7][M + 7];
inline void plus(int &a, LL b) { a = (a + b) % MOD; }
int main()
{
scanf("%d%d", &n, &m);
memset(f, 0, sizeof f);
f[0][0][0] = 1;
for (int i = 0; i < n; ++ i) for (int j = 0; j <= m; ++ j) for (int k = 0; k <= m; ++ k) if (f[i][j][k])
{
/* f[i][j][k] = f[i - 1][j][k];
if (j) plus(f[i][j][k], (LL)f[i - 1][j - 1][k] * (m - j - k + 1));
if (k) plus(f[i][j][k - 1], (LL)f[i - 1][j + 1][k - 1] * (j + 1));
if (j >= 2) plus(f[i][j - 2][k], (LL)f[i - 1][j - 2][k] * (m - j - k + 2) * (m - j - k + 1) / 2);
if (k >= 2) plus(f[i][j][k], (LL)f[i - 1][j + 2][k - 2] * (j + 2) * (j + 1) / 2);
if (j && k) plus(f[i][j][k], (LL)f[i - 1][j][k - 1] * (m - j - k + 1) * j); */
plus(f[i + 1][j][k], f[i][j][k]);
if (j + k < m) plus(f[i + 1][j + 1][k], (LL)f[i][j][k] * (m - j - k));
if (j) plus(f[i + 1][j - 1][k + 1], (LL)f[i][j][k] * j);
if (j + k <= m - 2) plus(f[i + 1][j + 2][k], (LL)f[i][j][k] * (m - j - k) * (m - j - k - 1) / 2);
if (j >= 2) plus(f[i + 1][j - 2][k + 2], (LL)f[i][j][k] * j * (j - 1) / 2);
if (j + k < m && j) plus(f[i + 1][j][k + 1], (LL)f[i][j][k] * (m - j - k) * j);
}
int ans = 0;
for (int i = 0; i <= m; ++ i) for (int j = 0; j <= m; ++ j) plus(ans, f[n][i][j]);
printf("%d\n", ans);
}
AHOI 2009 中国象棋的更多相关文章
- JZOJ 1667 ( bzoj 1801 ) [ AHOI 2009 ] 中国象棋 —— DP
题目:https://jzoj.net/senior/#main/show/1667 首先,一行.一列最多只有 2 个炮: 所以记录一下之前有多少行有 0/1/2 个炮,转移即可: 注意取模!小心在某 ...
- 中国象棋引擎的C#源代码
以前写的中国象棋引擎的C#源程序,可在VS2010中编译运行,由于个人精力有限,难以完成后续的开发工作,如果谁感兴趣,请关注微信公众号(“申龙斌的程序人生”,ID:slbGTD),发送后台消息“象棋引 ...
- BZOJ 1801中国象棋 DP
1801: [Ahoi2009]chess 中国象棋 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1426 Solved: 826[Submit][ ...
- C#中国象棋+游戏大厅 服务器 + 客户端源码
来源:www.ajerp.com/bbs C#中国象棋+游戏大厅 服务器 + 客户端源码 源码开源 C#版中国象棋(附游戏大厅) 基于前人大虾的修改版 主要用委托实现 服务器支持在线人数,大厅桌数的设 ...
- 1.2 中国象棋将帅问题进一步讨论与扩展:如何用1个变量实现N重循环?[chinese chess]
[题目] 假设在中国象棋中只剩下将帅两个棋子,国人都知道基本规则:将帅不能出九宫格,只能上下左右移动,不能斜向移动,同时将帅不能照面.问在这样条件下,所有可能将帅位置.要求在代码中只能使用一个字节存储 ...
- 基于HTML5实现的中国象棋游戏
棋类游戏在桌面游戏中已经非常成熟,中国象棋的版本也非常多.今天这款基于HTML5技术的中国象棋游戏非常有特色,我们不仅可以选择中国象棋的游戏难度,而且可以切换棋盘的样式.程序写累了,喝上一杯咖啡,和电 ...
- BZOJ 1801: [Ahoi2009]chess 中国象棋( dp )
dp(i, j, k)表示考虑了前i行, 放了0个炮的有j列, 放了1个炮的有k列. 时间复杂度O(NM^2) -------------------------------------------- ...
- cocos2d-x游戏开发系列教程-中国象棋02-main函数和欢迎页面
之前两个博客讲述了象棋的规格和工程文件之后,我们继续深入的从代码开始学习cocos2dx 首先从程序入口main函数开始 main函数 int APIENTRY _tWinMain(HINSTANCE ...
- cocos2d-x游戏开发系列教程-中国象棋01-工程文件概述
上一篇博文我们看到了象棋的效果图,这一张我们来看象棋代码的整体概述 让我们先对整个代码框架有个了解. 主目录: 主目录包含内容如上图: classes目录:业务代码 proj.win32:包括main ...
随机推荐
- python练习题及实现--文件处理、date日期
练习题作者:Vamei 出处:http://www.cnblogs.com/vamei http://www.cnblogs.com/vamei/archive/2012/07/19/2600135. ...
- NGUI-UIProgressBar,UIScrollBar,UISlider
UIProgressBar是UIScrollBar和UISlider的基类 1.先来看下UIProgressBar(进度条)的使用 层次: progressBar的Inspector视图: 而fore ...
- 孤荷凌寒自学python那些事第二天
孤荷凌寒自学python第二天 Python的变量声明 (完整学习过程屏幕记录视频在文末,手写笔记在文末) Python的变量声明不必要显式指定变量类型 甚至也不需要进行显式的声明 比javascri ...
- hnust 神奇的序列
问题 E: 神奇的序列 时间限制: 1 Sec 内存限制: 128 MB提交: 635 解决: 84[提交][状态][讨论版] 题目描述 Aurora在南宁发现了一个神奇的序列,即对 ...
- OpenCV实现张正友相机标定源代码
本源代码基于VC++和opencv Opencv2.4.13.6版本开发,实现张正友相机标定源代码,资源包括完整源代码和12张棋盘图片,完美运行.Opencv2.4.13.6安装包下载地址:http: ...
- Linux cooked-mode capture 格式转换
tcpdump抓包时,如果-i选项指定为一个网卡地址,那么抓取的数据包数据链路层是以太网头部:如果指定any,则以太网头部将被替换为linux cooked capture头部 # tcpdump - ...
- HDU 3874 Necklace 树状数组
题意:求区间内不同的数的和 离线处理,按查询右端点从小到大排序,从左往右扫一遍. 记录每个数出现的上一个位置,如果该数之前没有出现过,就加上,否则就在上一个位置减去. #include <cst ...
- 《机器学习实战》读书笔记—k近邻算法c语言实现(win下)
#include <stdio.h> #include <io.h> #include <math.h> #include <stdlib.h> #de ...
- json数据格式的简单案例
json数据是一种文本字符串,它是javascript的原生数据格式,在数据需要多次重复使用时,json数据是ajax请求的首先.(注:ajax返回的数据格式支持三种分别为:文本格式,json.和xm ...
- swiper伸缩侧边菜单栏
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...