Bzoj 1081 [Ahoi2009] chess 中国象棋
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 中国象棋的更多相关文章
- BZOJ 1801: [Ahoi2009]chess 中国象棋( dp )
dp(i, j, k)表示考虑了前i行, 放了0个炮的有j列, 放了1个炮的有k列. 时间复杂度O(NM^2) -------------------------------------------- ...
- bzoj 1801: [Ahoi2009]chess 中国象棋
Description 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放置方法,中国像棋中炮的行走方式大家应该很清楚吧. Input 一行包含两个整数N, ...
- [BZOJ 1801] [Ahoi2009]chess 中国象棋 【DP】
题目链接:BZOJ - 1801 题目分析 对于50%的数据是可以直接状压 DP 的. 对于100%的数据,使用递推的 DP .(或者这只叫递推不叫 DP ?) 可以发现,每一行和每一列的棋子个数不能 ...
- BZOJ 1801: [Ahoi2009]chess 中国象棋 [DP 组合计数]
http://www.lydsy.com/JudgeOnline/problem.php?id=1801 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放 ...
- bzoj 1801: [Ahoi2009]chess 中国象棋【dp】
注意到一行只能放012个炮,我们只需要知道列的状态,不用状压行 所以设f[i][j][k]表示前i行有j列有1个炮,有k列有2个炮的方案数 然后分情况讨论转移就行了 #include<cstdi ...
- BZOJ_1801_[Ahoi2009]chess 中国象棋_DP
BZOJ_1801_[Ahoi2009]chess 中国象棋_DP Description 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放置方法,中国像 ...
- 【BZOJ1801】[Ahoi2009]chess 中国象棋 DP
[BZOJ1801][Ahoi2009]chess 中国象棋 Description 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放置方法,中国像棋中炮 ...
- BZOJ1801 Ahoi2009 chess 中国象棋 【DP+组合计数】*
BZOJ1801 Ahoi2009 chess 中国象棋 Description 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放置方法,中国像棋中炮的行 ...
- BZOJ1801 [Ahoi2009]chess 中国象棋(DP, 计数)
题目链接 [Ahoi2009]chess 中国象棋 设$f[i][j][k]$为前i行,$j$列放了1个棋子,$k$列放了2个棋子的方案数 分6种情况讨论,依次状态转移. #include <b ...
随机推荐
- Python读取PDF文档
from pdfminer.converter import PDFPageAggregator from pdfminer.layout import LAParams from pdfminer. ...
- Subversion Server Edge的搭建与配置
1.Subversion Server Edge的搭建 当在操作系统为64位的配置服务器上部署时只能够选择Collabnet Subversion Edge,它集合了Subversion所需要一切资源 ...
- 禁用thinkpad触摸板的方法
控制面板----硬件和声音----设备和打印机----鼠标----ThinkPad------开启触摸板(前面的勾勾去掉)
- Windows 命令行基础(博主推荐)
不多说,直接上干货! 见 https://blog.henix.info/blog/windows-cmdbasic/
- 【Java密码学】用Java数字签名提供XML安全
简介 众所周知,XML在产品和项目开发中起着非常重要的作用.通过XML文档可以获取很多信息,还可以使用XML文件进行CRUD(增加.查询.更新和删除)操作.然而值得注意的是,我们如何确保XML中的数据 ...
- Backbone源码风格
代码风格: 一.自执行匿名函数创建执行环境 var root = this; root保存全局执行环境的指针.浏览器端为window对象 二.依赖库 (1).underscore 如果bac ...
- 《Head First 设计模式》之迭代器与组合模式——遍历合并的菜单
迭代器与组合模式(Iterator & Composite) 迭代器:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. 组合:允许你将对象组成树形结构来表现“整体.部分” ...
- vue awaresome swiper的使用
main.jsimport VueAwesomeSwiper from 'vue-awesome-swiper'import 'swiper/dist/css/swiper.css'Vue.use(V ...
- form表单多文件上传
1.html/jsp主页 <%@ page language="java" contentType="text/html; charset=UTF-8" ...
- LeetCode(605,581,566)
LeetCode(605,581,566) 摘要:605盲改通过:581开始思路错误,后利用IDE修改(多重循环跳出方法):566用C语言时需要动态内存分配,并且入口参数未能完全理解,转用C++. 6 ...