题面

题目描述

这次小可可想解决的难题和中国象棋有关,在一个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. Vue_初识

    前端三大框架: vue:开发效率相当高了. angalar:适合做后台管理系统,入手容易,但是越往后会越难受. react:虚拟dom(渲染内存中存储的dom,经过操作后,才会去渲染浏览器的真实dom ...

  2. pin

    sjhh@123456 Michael zhang zhangxiaocong_2011@yeah.net

  3. vue 实例 网站

    Pure vue demo 实战第一节:Vue基础一 Pure vue demo 实战第二节:Vue基础二 Pure vue demo 实战第三节:Vue组件 Pure vue demo 实战第四节: ...

  4. pyinstaller打包自己的python程序

    使用Pyinstaller打包步骤如下 1. 安装pyinstaller pip install pyinstaller 查看安装的版本 pyinstaller --version 2. 给脚本加密 ...

  5. Spring 对属性文件的加密与解密

    一般用于配置密码等敏感信息 解密/加密工具类 package com.baobaotao.placeholder; import sun.misc.BASE64Decoder; import sun. ...

  6. 湘潭邀请赛 2018 I Longest Increasing Subsequence

    题意: 给出一个长度为n的序列,序列中包含0.定义f(i)为把所有0变成i之后的Lis长度,求∑ni=1i⋅f(i). 题解: 设不考虑0的Lis长度为L,那么对于每个f(i),值为L或L+1. 预处 ...

  7. [poj] 1204 Word Puzzles || AC自动机

    原题 给个X*Y的字符串矩阵,W个询问,对每个询问输出这个串出现的位置及方向,共有8个方向,顺时针开始分别用A~H表示 AC自动机的板子题. 对于待匹配串建一个自动机,然后从矩阵的四周分别沿八个方向跑 ...

  8. 3.1 Java以及Lucene的安装与配置

    Lucene是Java开发的一套用于全文检索和搜索的开源程序库,它面向对象多层封装,提供了一个低耦合.与平台无关的.可进行二次开发的全文检索引擎架构,是这几年最受欢迎的信息检索程序库[1].对Luce ...

  9. CSU 2136 ——湖南多校对抗赛 I

    2136: 统帅三军! Submit Page   Summary   Time Limit: 1 Sec     Memory Limit: 128 Mb     Submitted: 55     ...

  10. Pandas之DataFrame——Part 1

    ''' [课程2.] Pandas数据结构Dataframe:基本概念及创建 "二维数组"Dataframe:是一个表格型的数据结构,包含一组有序的列,其列的值类型可以是数值.字符 ...