BZOJ原题链接

洛谷原题链接

这题挺难想状态的,刚看题感觉是状压,但数据\(100\)显然不可能。

注意到每行每列只能放\(0\sim 2\)个棋子,所以我们可以将这个写入状态。

设\(f[i][j][k]\)表示放了前\(i\)行,共有\(j\)列只放了一个棋子,共有\(k\)列放了两个棋子,而没有放棋子的列数则可以直接计算,即\(m - j - k\)。

然后分类讨论。


  • 第\(i\)行不放

    只有一种放法,直接由上一层转移:$$f[i][j][k] = f[i][j][k] + f[i - 1][j][k]$$

  • 第\(i\)行放一个棋子
  1. 放在原本没有放棋子的列上,共\(m - (j - 1) - k\)种放法:$$f[i][j][k] = f[i][j][k] + f[i - 1][j - 1][k] \times (m - (j - 1) - k)$$
  2. 放在原本只有一个棋子的列上,共\(j + 1\)种放法:$$f[i][j][k] = f[i][j][k] + f[i - 1][j + 1][k - 1] \times (j + 1)$$

  • 第\(i\)行放两个棋子
  1. 都放在原本没有放棋子的列上,共\(C_{m - (j - 2) - k} ^ 2\)种放法:$$f[i][j][k] = f[i][j][k] + f[i - 1][j - 2][k] \times C_{m - (j - 2) - k} ^ 2$$
  2. 一个放在空列,一个放在原本只有一个棋子的列上,共\(j \times (m - j - (k - 1))\)种放法:$$f[i][j][k] = f[i][j][k] + f[i - 1][j][k - 1] \times j \times (m - j - (k - 1))$$
  3. 都放在原本只有一个棋子的格子上,共\(C_{j + 2} ^ 2\)种放法:$$f[i][j][k] = f[i][j][k] + f[i - 1][j + 2][k - 2] \times C_{j + 2} ^ 2$$

初值\(f[0][0][0] = 1\),其它为\(0\)。

在\(DP\)过程中注意取模和边界问题。

最后答案就是\(\sum\limits_{i = 0} ^ m \sum \limits _{j = 0} ^ m f[n][i][j]\)。

  1. #include<cstdio>
  2. using namespace std;
  3. const int N = 110;
  4. const int mod = 9999973;
  5. int f[N][N][N];
  6. inline int re()
  7. {
  8. int x = 0;
  9. char c = getchar();
  10. bool p = 0;
  11. for (; c < '0' || c > '9'; c = getchar())
  12. p |= c == '-';
  13. for (; c >= '0' && c <= '9'; c = getchar())
  14. x = x * 10 + c - '0';
  15. return p ? -x : x;
  16. }
  17. inline int C(int x)
  18. {
  19. return (1LL * x * (x - 1) >> 1) % mod;
  20. }
  21. int main()
  22. {
  23. int i, j, k, n, m, s = 0;
  24. n = re();
  25. m = re();
  26. f[0][0][0] = 1;
  27. for (i = 1; i <= n; i++)
  28. for (j = 0; j <= m; j++)
  29. for (k = 0; k + j <= m; k++)
  30. {
  31. f[i][j][k] = f[i - 1][j][k];
  32. if (k)
  33. {
  34. f[i][j][k] = ((1LL * f[i - 1][j + 1][k - 1] * (j + 1) % mod) + f[i][j][k]) % mod;
  35. f[i][j][k] = ((1LL * f[i - 1][j][k - 1] * j % mod * (m - j - k + 1) % mod) + f[i][j][k]) % mod;
  36. }
  37. if (j)
  38. f[i][j][k] = ((1LL * f[i - 1][j - 1][k] * (m - j - k + 1) % mod) + f[i][j][k]) % mod;
  39. if (j > 1)
  40. f[i][j][k] = ((1LL * f[i - 1][j - 2][k] * C(m - j - k + 2) % mod) + f[i][j][k]) % mod;
  41. if (k > 1)
  42. f[i][j][k] = ((1LL * f[i - 1][j + 2][k - 2] * C(j + 2) % mod) + f[i][j][k]) % mod;
  43. }
  44. for (i = 0; i <= m; i++)
  45. for (j = 0; j <= m; j++)
  46. s = (1LL * s + f[n][i][j]) % mod;
  47. printf("%d", s);
  48. return 0;
  49. }

BZOJ1801或洛谷2051 [AHOI2009]中国象棋的更多相关文章

  1. 洛谷.2051.[AHOI2009]中国象棋(DP)

    题目链接 /* 每行每列不能超过2个棋子,求方案数 前面行对后面行的影响只有 放了0个.1个.2个 棋子的列数,与排列方式无关 所以设f[i][j][k]表示前i行,放了0个棋子的有j列,放了1个棋子 ...

  2. 洛谷2051 [AHOI2009]中国象棋

    题目链接 题意概述:n行m列棋盘放若干个棋子每行每列最多两个求方案总数,答案对9999973取模. 可以比较容易看出这是个dp,设f[i][j][k]表示前i行j列放1个棋子k列放2个棋子的方案总数. ...

  3. [洛谷P2051] [AHOI2009]中国象棋

    洛谷题目链接:[AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法 ...

  4. 洛谷 P2051 [AHOI2009]中国象棋 解题报告

    P2051 [AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法. ...

  5. 洛谷 P2051 [AHOI2009]中国象棋 状态压缩思想DP

    P2051 [AHOI2009]中国象棋 题意: 给定一个n*m的空棋盘,问合法放置任意多个炮有多少种情况.合法放置的意思是棋子炮不会相互打到. 思路: 这道题我们可以发现因为炮是隔一个棋子可以打出去 ...

  6. 洛谷 P2051 [AHOI2009]中国象棋

    题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中国象棋中炮的行走方式是 ...

  7. 洛谷P2051 [AHOI2009]中国象棋(dp)

    题面 luogu 题解 \(50pts:\)显然是\(3\)进制状压\(dp\) \(100pts:\) 一行一行地考虑 \(f[i][j][k]\)表示前\(i\)行,有\(j\)列放了一个,有\( ...

  8. 洛谷P2051 [AHOI2009] 中国象棋(状压dp)

    题目简介 n*m的棋盘,对每行放炮,要求每行每列炮数<=2,求方案数%9999973 N,M<=100 题目分析 算法考虑 考虑到N,M范围较小,每一行状态只与前面的行状态有关,考虑状压D ...

  9. luogu 2051 [AHOI2009]中国象棋

    luogu 2051 [AHOI2009]中国象棋 真是一道令人愉♂悦丧心并框的好题... 首先"没有一个炮可以攻击到另一个炮"有个充分条件就是没有三个炮在同一行或同一列.证明:显 ...

随机推荐

  1. Keil 报错汇总

    main.c(6): warning:  #1-D: last line of file ends without a newline 解决:main.c 最后一行加回车就可以了. keil中文注释出 ...

  2. vue --轮播图

    轮播图,可以使用mint-ui中的swipe HTML: <Swipe :auto="4000"> <SwipeItem v-for="item in ...

  3. Linux 中文输入法安装

    问题一:文本不能输入中文,所以考虑到要安装搜狗输入法,在 Oracle VM VirtualBox 新建的Ubuntu系统应用中心,安装输入法总是安装失败,在自己电脑上下载了Linux的输入法文件. ...

  4. User-Defined Components Must Be Capitalized

    [User-Defined Components Must Be Capitalized] When an element type starts with a lowercase letter, i ...

  5. excel表格输入思想

    1.创建工作簿  SXSSFWorkbook wb = new SXSSFWorkbook(); //#设置单元格的垂直居中,水平居中,字体颜色 2.创建sheet  Sheet sheet = wb ...

  6. python文件操作 二

    问题:在传输的时候对方不知道是以什么格式传给用户,传来传去彼此都忘了什么格式: 在编码的时候:utf8:是3个字符,gbk是2个字符,每个字符数字对应的字符,一段2进制串,如果10个字节全部都是中文, ...

  7. angularjs 获取$scope对象

    参考 https://blog.csdn.net/u011974399/article/details/77865293 angular.element("[ng-controller=xx ...

  8. SQLdeveloper同时显示多个表的窗口

  9. POJ-2251.DungeonMaster(三维BFS)

    做题时需要注意,爬楼有向上和向下爬之分... 本题大意:输入 l, r, c, 分别代表地牢的楼层数和每层地牢的长和宽,地牢由rock and point and source and key组成,你 ...

  10. 微信小程序开发——小程序API获取用户位置及异常流处理完整示例

    前言: 小程序需要添加一个定位功能,主要的就是获取用户位置的经纬度,然后根据用户经纬度进行一些判断操作. 在小程序提供的Api中,获取用户定位信息的主要Api是 wx.getLocation(obj) ...