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 ...
随机推荐
- nosetests
1.nosetests 执行出测试报告 提前安装 插件nose-html系列插件 nosetests -v --with-html-output --html-out-file=报告名.html ...
- sqlserver 列出表字段和字段说明
--表描述SELECT tbs.name 表名,ds.value 描述 FROM sys.extended_properties dsLEFT JOIN sysobjects tbs ON ds.ma ...
- 聊聊、Mybatis Java注解实现
AbstractAnnotationConfigDispatcherServletInitializer public class MvcInitializer extends AbstractAnn ...
- PHP连接mysql数据库进行增删改查--修稿数据
<?php $id = $_GET['id']; $db = new Mysqli("localhost","root","root" ...
- airTest 实战之 -- 【征途】自动打怪回城卖物品
airTest是一个跨平台的.基于图像识别的UI自动化测试框架,适用于游戏和App,支持平台有Windows.Android和iOS 官方文档: http://airtest.netease.com/ ...
- qemu中device和driver的区别 使用9p文件系统
qemu配置中经常会出现-driver/-device的选项,可以理解成-driver是后端设备,即一个实际的物理的磁盘:device是把这块磁盘插入到虚机中的pci控制器中. 这样的话,虚机也能看到 ...
- Linux系统——C/C++开发工具及环境搭建
首先,我们是要在Linux下进行项目开发,让我们把windows“拆了”,装个Linux也是不可能的,会带来很多的不便,所以我们首先需要在虚拟机上安装Linux操作系统,我本次用的是CentOS,它也 ...
- code forces 994B
B. Knights of a Polygonal Table time limit per test 1 second memory limit per test 256 megabytes inp ...
- Python学习笔记(Django篇)——4、继续完善视图层
在demo/views.py中添加这些代码: def detail(request, question_id): returnHttpResponse("You're looking at ...
- UVa10025 The ? 1 ? 2 ? ... ? n = k problem 数学思维+规律
UVa10025 ? 1 ? 2 ? ... ? n = k problem The problem Given the following formula, one can set operator ...