bzoj 1081 [Ahoi2009] chess 中国象棋

题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1801

状态比较难设,的确没想到.

不关心第几列出现是否出现了棋子的个数.而是看看上一行第几列出现了1或2个棋子

利用组合巧妙解决问题.

设\(f[i][j][k]\)表示第i行有j列有1个棋子.有k行有2个棋子.

那么为空的即为\(m - j - k\)

状态转移方程:

1.这一行什么都不放:

\(f[i][j][k] += f[i - 1][j][k]\)

2.这一行放一个 在空行上放

\(f[i][j][k] += f[i - 1][j - 1][k] * (m - (j - 1) - k);\)

3.这一行放一个 在有一个棋子放

\(f[i][j][k] += f[i - 1][j + 1][k - 1] * (j + 1);\)

4.这一行放两个 都在一个棋子上放

\(f[i][j][k] += f[i - 1][j + 2][k - 2] * C(j + 2,2);\)

5.这一行放两个 在没有棋子上面放

\(f[i][j][k] += f[i - 1][j - 2][k] * C(m - j - k + 2,2);\)

6.这一行一个棋子在一个棋子的列上放,一个棋子在没有棋子的列上方

\(f[i][j][k] += f[i - 1][j][k - 1] * j * (m - j - k + 1)\)

边界的话:当然是\(f[0][0][0] = 1\)啦

滚动一下数组非常快

/*
卡常记录 :
总耗时 : 111ms -> 86ms
最高用时 : 23ms -> 17ms
*/
#include <iostream>
#include <cstdio>
#define rep(i,x,p) for(register int i = x;i <= p;++ i)
#define sep(i,x,p) for(register int i = x;i >= p;-- i)
#define gc getchar()
#define pc putchar
const int maxN = 100 + 7;
const int mod = 9999973; long long f[2][maxN][maxN];
int n,m; inline int read() {
int x = 0,f = 1;char c = gc;
while(c < '0' || c > '9') {if(c == '-')f = -1;c = gc;}
while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = gc;}
return x * f;
} inline int C(int n) {
return n * ( n - 1 ) / 2;
} int main() {
f[0][0][0] = 1;
int n,m;
n = read();m = read();
rep(i,1,n) {
int x = i % 2,q = x ? 0 : 1;
rep(j , 0 , m) {
for(register int k = 0;k + j <= m;++ k) {
f[x][j][k] = f[q][j][k];
if(j >= 1) f[x][j][k] += f[q][j - 1][k] * (m - (j - 1) - k);
if(k >= 1) f[x][j][k] += f[q][j + 1][k - 1] * (j + 1);
if(k >= 2) f[x][j][k] += f[q][j + 2][k - 2] * C(j + 2);
if(j >= 2) f[x][j][k] += f[q][j - 2][k] * C(m - j - k + 2);
if(k >= 1) f[x][j][k] += f[q][j][k - 1] * j * (m - j - k + 1);
f[x][j][k] %= mod;
}
}
}
long long ans = 0,x = n % 2;
rep(j , 0 , m) {
for(register int k = 0;k + j <= m;++ k)
ans += f[x][j][k];
ans %= mod;
}
printf("%lld\n", ans);
return 0;
}

Bzoj 1081 [Ahoi2009] chess 中国象棋的更多相关文章

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

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

  2. bzoj 1801: [Ahoi2009]chess 中国象棋

    Description 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放置方法,中国像棋中炮的行走方式大家应该很清楚吧. Input 一行包含两个整数N, ...

  3. [BZOJ 1801] [Ahoi2009]chess 中国象棋 【DP】

    题目链接:BZOJ - 1801 题目分析 对于50%的数据是可以直接状压 DP 的. 对于100%的数据,使用递推的 DP .(或者这只叫递推不叫 DP ?) 可以发现,每一行和每一列的棋子个数不能 ...

  4. BZOJ 1801: [Ahoi2009]chess 中国象棋 [DP 组合计数]

    http://www.lydsy.com/JudgeOnline/problem.php?id=1801 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放 ...

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

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

  6. BZOJ_1801_[Ahoi2009]chess 中国象棋_DP

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

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

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

  8. BZOJ1801 Ahoi2009 chess 中国象棋 【DP+组合计数】*

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

  9. BZOJ1801 [Ahoi2009]chess 中国象棋(DP, 计数)

    题目链接 [Ahoi2009]chess 中国象棋 设$f[i][j][k]$为前i行,$j$列放了1个棋子,$k$列放了2个棋子的方案数 分6种情况讨论,依次状态转移. #include <b ...

随机推荐

  1. React学习记录

    托webpack的福,我终于可以开始写React了.==ORZ 我感觉我接近webpack工程师更进一步了哈哈哈. 以下所有内容均来自小红书,仅是我的个人记录,如想系统学习,请移步:React小书 : ...

  2. JAVA对象转换JSON

    1. 把java 对象列表转换为json对象数组,并转为字符串 复制代码 代码如下: JSONArray array = JSONArray.fromObject(userlist); String ...

  3. 文件系统满的话(filesystem full),该如何处理。(du and ls)

    #!/bin/bash function ergodic(){ ` do "/"$file ] then ergodic $"/"$file else loca ...

  4. js中的onclick事件传参需要注意的问题

    如果参数是数值类型可以直接传,如果是字符串类型需要在字符串前后加上双引号,双引号需要转义 如 onclick="test(0)";  直接传值 参数为数值 onclick=&quo ...

  5. Java关键字和基础问题

    1. Java关键字 1.1 extends和implements extends继承普通class或abstract(抽象)类(java单继承) implements多继承能力,实现interfac ...

  6. vnc安装问题

    在xenserver中安装vncserver软件.启动显示正常 用grep命令查看也确实有线程在运行. 但实际上用命令service vncserver status查看vnc状态,显示没有桌面在运行 ...

  7. 两道sql面试题

    两道sql面试题:    1. 数据库表A的数据如下:             year   quarter             2001      1             2001      ...

  8. UICollectionView笔记1

    WWDC 2012 Session笔记——205 Introducing Collection Views 这是博主的WWDC2012笔记系列中的一篇,完整的笔记列表可以参看这里.如果您是首次来到本站 ...

  9. 用python计算直角三角形斜边长

    直接上代码 import math def hypotenuse(a,b): return(math.sqrt(a**2+b**2)) side1 = int(input("第一条直角边:& ...

  10. ABAP ICON

    1.输出图标的3种方法 WRITE: / '@09@'. "id WRITE: / icon_yellow_light. "name WRITE: / '@S_TL_Y@'. &q ...