题意:

在n * m 的棋盘上放"炮",使得任意两个炮都不会互相攻击,求方案数。

题解:

既然是求方案数,那么考虑数学方法和递推,这一道题的限制条件比较麻烦,数学方法不合适,考虑递推。

现在考虑定义状态,很显然一维需要行数,表示考虑了前i行,现在在第i行放棋子,需要明白的是每一行每一列最多放两个炮,那么放棋子是有限制条件的,也就是每一列的已经放了的棋子数目在限制当前的放法,那么我们需要再开三维表示,没放棋子的列数,放一个棋子的列数,放两个棋子的列数,仔细一想没放棋子的列数可以通过后两个计算出来,并且第一维也可以滚动起来。

那么转移也变得很显然了。

1.第i行不放棋子。

2.第i行只放一个棋子 : ①放在没放棋子的那一列 ②放在放了一个棋子的那一列

3.第i行放两个棋子: ①全都放在没放棋子的列上 ②分别放在没放棋子的列和放了一个棋子的列上 ③全都放在放了一个棋子的列上

代码:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;#define ll long long
const int N = 1e2 + 7;
const int mod = 9999973;
int n, m;
ll dp[N][N][N];int calc (int x) {return x * (x - 1) / 2;
}int main () {scanf ("%d%d", &n, &m);dp[0][0][0] = 1;for (int i = 1; i <= n; ++i) {for (int j = 0; j <= m; ++j) {for (int k = 0; k <= m; ++k) {dp[i][j][k] += dp[i - 1][j][k];if (j >= 1) dp[i][j][k] += dp[i - 1][j - 1][k] * (m - j - k + 1);if (j >= 2) dp[i][j][k] += dp[i - 1][j - 2][k] * calc(m - k - j + 2);if (k >= 1 && j <= m - 1) dp[i][j][k] += dp[i - 1][j + 1][k - 1] * (j + 1);if (k >= 2 && j <= m - 2) dp[i][j][k] += dp[i - 1][j + 2][k - 2] * calc(j + 2);if (k >= 1) dp[i][j][k] += dp[i - 1][j][k - 1] * (m - k - j + 1) * j;dp[i][j][k] %= mod;}}}ll ret = 0;for (int j = 0; j <= m; ++j) for (int k = 0; k <= m; ++k) ret = (ret + dp[n][j][k]) % mod;cout << ret << endl;return 0;
}

  

转载于:https://www.cnblogs.com/xgtao/p/5991072.html

BZOJ 1801 chess 中国象棋相关推荐

  1. BZOJ 1801 [Ahoi2009]中国象棋(线性动规)(洛谷P2051)

    题意:就是在n*m的格子中放"炮"(中国象棋中的棋子)问有多少种放法,使得没有任意的两个炮相互攻击 思路:我们很容易的得到一列或者一行中最多放下两个炮(我也只能得到这些了,满脑子状 ...

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

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

  3. bzoj 1801: [Ahoi2009]chess 中国象棋 bzoj 4806: 炮

    1801: [Ahoi2009]chess 中国象棋 Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 1851  Solved: 1062 [Submi ...

  4. BZOJ1801: [Ahoi2009]chess 中国象棋

    BZOJ1801: [Ahoi2009]chess 中国象棋 Description 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放置方法,中国像棋中炮 ...

  5. bzoj 1801: [Ahoi2009]chess 中国象棋【dp】

    注意到一行只能放012个炮,我们只需要知道列的状态,不用状压行 所以设f[i][j][k]表示前i行有j列有1个炮,有k列有2个炮的方案数 然后分情况讨论转移就行了 #include<cstdi ...

  6. BZOJ 1801 AHOI 2009 chess 中国象棋 DP

    题目大意:给出棋盘的大小,问任意行和列放置的棋子都不超过两个有多少种方案. 思路:一个比较麻烦的DP.f[i][j][k]表示到前i行,放置了一个棋子的列为j,放置了两个棋子的列为k的方案数,然后有六 ...

  7. 【BZOJ1801】【DTOJ2004】 [Ahoi2009]chess 中国象棋 【DP】

    题解: 首先知道一个性质,每一行每一列都最多有两个炮 那么很显然是DP 设F[i][j][k]表示前i行,有j列有一个炮,有k列有两个炮,那么转移式子为 这一行什么都不做:f[i][j][k]=f[i ...

  8. 2017.10.23 chess 中国象棋 思考记录

    这种题的一般解法: 1. 发现状压可以搞,然后发现状态爆炸 2.考虑状态特点,一共只有几种可能的状态 3.考虑可不可以只对状态进行计数 4.离散统计贡献 码: #include<iostream ...

  9. [AHOI 2009]chess 中国象棋

    Description 题库链接 给你一张 \(N\times M\) 的棋盘.要求每行每列最多放两个棋子,问总方案数. \(1\leq N,M\leq 100\) Solution 记 \(f_{i ...

最新文章

  1. Python-str函数
  2. 数据结构和算法分析:第一章 引论
  3. Vue.js指令实例
  4. oracle数据block默认是,oracleBLOCK(数据块)
  5. HttpClinet学习笔记
  6. Rds基于mysql开发的_开发云数据库RDS MYSQL版讲解
  7. C语言 printf函数实现
  8. A股开盘:深证区块链50指数涨0.94%,*ST晨鑫涨停
  9. Channel shutdown: channel error; protocol method
  10. java与jsp的关系_浅谈servlet与jsp的关系
  11. 利用IS61LV12816实现DSP28335的内存扩展
  12. 三菱J4伺服驱动器拨码
  13. 3ds max软件如何彻底卸载干净
  14. 【Hive】Establishing SSL connection without server‘s identity verification is not recommended. Accord
  15. 什么是高中物理?一篇长长长长文告诉你!
  16. Python - 列表补充(二)
  17. java实现 xls转xlsx
  18. 1 什么叫多媒体计算机,选择1多媒体计算机中的媒体信息是指()文字声音.ppt
  19. char c1,c2;与int c1,c2是否无条件地等价.cpp
  20. Jmeter 压测工具

热门文章

  1. C语言 makefile
  2. 数据算法之二叉树插入(BinaryTreeL Insert)的Java实现
  3. Java折叠_[Java教程]Jquery中菜单的展开和折叠
  4. word vba 点击任意域代码,刷新整个文档的域代码值
  5. 九种分布式ID生成方式
  6. 计算机行业深度分析,广发证券计算机行业深度分析
  7. php 时间戳存储 原因,将php文件中的unix时间戳存储到mysql中(store unix timestamp from php file into mysql)...
  8. java学生奖学金管理系统_EasyUI+JavaWeb奖助学金管理系统[6]-登录功能实现
  9. 雷军定AI+IoT为小米核心战略,牵手宜家推进生态布局
  10. 【邀请函】第十届中国电子政务高峰论坛即将开幕