题面

题目描述

这次小可可想解决的难题和中国象棋有关,在一个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 中国象棋的更多相关文章

  1. JZOJ 1667 ( bzoj 1801 ) [ AHOI 2009 ] 中国象棋 —— DP

    题目:https://jzoj.net/senior/#main/show/1667 首先,一行.一列最多只有 2 个炮: 所以记录一下之前有多少行有 0/1/2 个炮,转移即可: 注意取模!小心在某 ...

  2. 中国象棋引擎的C#源代码

    以前写的中国象棋引擎的C#源程序,可在VS2010中编译运行,由于个人精力有限,难以完成后续的开发工作,如果谁感兴趣,请关注微信公众号(“申龙斌的程序人生”,ID:slbGTD),发送后台消息“象棋引 ...

  3. BZOJ 1801中国象棋 DP

    1801: [Ahoi2009]chess 中国象棋 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1426  Solved: 826[Submit][ ...

  4. C#中国象棋+游戏大厅 服务器 + 客户端源码

    来源:www.ajerp.com/bbs C#中国象棋+游戏大厅 服务器 + 客户端源码 源码开源 C#版中国象棋(附游戏大厅) 基于前人大虾的修改版 主要用委托实现 服务器支持在线人数,大厅桌数的设 ...

  5. 1.2 中国象棋将帅问题进一步讨论与扩展:如何用1个变量实现N重循环?[chinese chess]

    [题目] 假设在中国象棋中只剩下将帅两个棋子,国人都知道基本规则:将帅不能出九宫格,只能上下左右移动,不能斜向移动,同时将帅不能照面.问在这样条件下,所有可能将帅位置.要求在代码中只能使用一个字节存储 ...

  6. 基于HTML5实现的中国象棋游戏

    棋类游戏在桌面游戏中已经非常成熟,中国象棋的版本也非常多.今天这款基于HTML5技术的中国象棋游戏非常有特色,我们不仅可以选择中国象棋的游戏难度,而且可以切换棋盘的样式.程序写累了,喝上一杯咖啡,和电 ...

  7. BZOJ 1801: [Ahoi2009]chess 中国象棋( dp )

    dp(i, j, k)表示考虑了前i行, 放了0个炮的有j列, 放了1个炮的有k列. 时间复杂度O(NM^2) -------------------------------------------- ...

  8. cocos2d-x游戏开发系列教程-中国象棋02-main函数和欢迎页面

    之前两个博客讲述了象棋的规格和工程文件之后,我们继续深入的从代码开始学习cocos2dx 首先从程序入口main函数开始 main函数 int APIENTRY _tWinMain(HINSTANCE ...

  9. cocos2d-x游戏开发系列教程-中国象棋01-工程文件概述

    上一篇博文我们看到了象棋的效果图,这一张我们来看象棋代码的整体概述 让我们先对整个代码框架有个了解. 主目录: 主目录包含内容如上图: classes目录:业务代码 proj.win32:包括main ...

随机推荐

  1. Mysql DISTINCT问题

    问题描述 因为要设计一个数据库表,进行一个倒序去重的操作. 例如: id Name 1 B 2 A 3 A 4 C 5 C 6 B 场景:例如说我们需要得到一个用户的搜索记录,那么肯定不会仅仅根据时间 ...

  2. HDU 4417 Super Mario ( 离线树状数组 )

    把数值和查询放在一起从小到大排序,纪录每个数值的位置,当遇到数值时就更新到树状数组中,遇到查询就直接查询该区间和. #include <cstdio> #include <cstri ...

  3. 29个android开发常用的类、方法及接口

    在安卓开发中,我们常常都需要借助各种各样的方法.类和接口来实现相关功能.提升开发效率,但对于初学者而言,什么时候该用什么类.方法和接口呢?下面小编整理了29个,日常开发中比较常用的类.方法.接口及其应 ...

  4. [BZOJ4205][FJ2015集训] 卡牌配对 [建图+最大流]

    题面 这是bzoj权限题,题面可以去下面的离线题库找 离线4205,只有题面,不能提交 思路 二分图匹配 这道题模型显然就是个二分图匹配嘛 那我们两两判断一下然后连边匹配.....就只有30分了 因为 ...

  5. 如何写出高质量的JavaScript代码

    优秀的Stoyan Stefanov在他的新书中(<Javascript Patterns>)介绍了很多编写高质量代码的技巧,比如避免使用全局变量,使用单一的var关键字,循环式预存长度等 ...

  6. struts2之文件上传

    一.单文件上传 实例: 表单应该注意三个点   form中的method="post".enctype="multipart/form-data".input中 ...

  7. 一种简单高效的音频降噪算法示例(附完整C代码)

    近期比较忙, 抽空出来5.1开源献礼. 但凡学习音频降噪算法的朋友,肯定看过一个算法. <<语音增强-理论与实践>> 中提及到基于对数的最小均方误差的降噪算法,也就是LogMM ...

  8. vue-cli脚手架的.babelrc文件

    虽然es6还没被浏览器全部支持,但是使用es6是大势所趋,所以babel应运而生将es6代码转换成浏览器能够识别的代码 什么是.babelrc文件呢? 熟悉linux的同学一定知道,rc结尾的文件通常 ...

  9. Data_Structure01-绪论作业!

    一.作业题目 仿照三元组或复数的抽象数据类型写出有理数抽象数据类型的描述 (有理数是其分子.分母均为整数且分母不为零的分数). 有理数基本运算: 构造有理数T,元素e1,e2分别被赋以分子.分母值 销 ...

  10. 关于JSON的简介及取值以及常见面试题

    关于JSON的简介及取值 JSON(JavaScript Object Notation)一种轻量级的数据交互格式 类似于一种数据封装,可以想象为java中student封装类 JSON的数值可以是数 ...