2016 Multi-University Training Contest 1 I. Solid Dominoes Tilings
Solid Dominoes Tilings
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 235 Accepted Submission(s): 143
The tiling is called solid if it is not possible to split the tiled rectangle by a straight line, not crossing the interior of any tile. For example, on the picture below the tilings (a) and (b) are solid, while the tilings (c) and (d) are not.

Now the managers of the company wonder, how many different solid tilings exist for an m × n rectangle. Help them to find that out.
5 6
8 7
6
13514
All solid tilings for the 5×6 rectangle are provided on the picture below:

题意:
在经典的多米诺骨牌覆盖上加入限制:
覆盖后的骨牌不能被一条直线(横切、竖切)分成两部分。
求合法覆盖的方案数。
题解:
....这道题...以它的数据组数,除了在预处理出所有答案后打表,貌似没办法了.....
还有题解里面说的轮廓线dp是什么鬼?
不是状压dp一下就搞定了吗? 当然,这题比较好的一点,也是卡住我的一点就是其中的一个容斥过程。 1、首先状压dp出g[n][m]表示大小为n*m的时候,随意放置的方案数。
可以先深搜出所有的合法转移状态,存储到邻接表中。
显然合法转移数很少,那么,即使是在m=16时也只有100w种。
1<=m<=16的总转移数也只有200w种
所以这一步的总复杂度为O(n*总转移数) 2、接着,暴力来说,我们对于每个矩阵只要枚举矩阵的列的分割线,就能容斥了。
这样容斥出来的是列不能分割的情况。
行的如果在容斥一遍就不行了。
我一开始完全没有想到预处理答案打表。。。造成了思路的阻塞。。。
其实对于某种列的分割情况来说,
行的情况,是可以递推得:
令F[n]表示长为n的棋盘在枚举的宽度m且在枚举的切割方案下的行稳定方案。
那么显然
F[n] = g[n][m] - F[1]*g[n-1][m] - ..... -F[n - 1]*g[1][m]
即,利用第一条分割线做容斥。
这一步要O(n^2)
所以整个第二步打表过程要O(sigma(2^(m-1)*n*n), 1<= m <= 16)
即O(2^m * n^2) 从复杂度来说,我的方法应该是比较快的。
const int N = , M = , MOD = 1e9 + ;
int head[ << N], son[M], nex[M], tot;
int ans[N][N], blocks[N];
int width;
int G[N][ << N], g[N][N]; inline int add(int x, int y) {
return ((x + y) % MOD + MOD) % MOD;
} inline int mul(int x, int y) {
return ((x * 1ll * y) % MOD + MOD) % MOD;
} inline void addEdge(int u, int v) {
son[tot] = v, nex[tot] = head[u];
head[u] = tot++;
} inline void searchNexState(int goalState, int nowState, int d) {
if(d == width) addEdge(goalState, nowState);
else if((goalState >> d) & ) {
if(d < width - && (goalState >> (d + ) & )) {
int nexState = nowState;
nexState |= ( << d) | ( << (d + ));
searchNexState(goalState, nexState, d + );
}
searchNexState(goalState, nowState, d + );
} else searchNexState(goalState, nowState | ( << d), d + );
} inline void getTransfer(int n) {
width = n, tot = ;
for(int i = ; i < ( << n); ++i) {
head[i] = -;
searchNexState(i, , );
}
// printf("%d\n", tot);
} inline void getG(int n, int m) {
for(int tab = head[( << m) - ]; tab != -; tab = nex[tab])
G[][son[tab]] = ;
for(int i = ; i < n; ++i) {
for(int u = ; u < ( << m); ++u) G[i + ][u] = ;
for(int u = ; u < ( << m); ++u) {
if(G[i][u]) {
for(int tab = head[u]; tab != -; tab = nex[tab])
G[i + ][son[tab]] = add(G[i + ][son[tab]], G[i][u]);
}
}
}
for(int i = ; i <= n; ++i) g[i][m] = G[i][( << m) - ];
} inline void search(int w, int now, int len) {
if(w >= width) {
blocks[len++] = now;
static int F[N], G[N];
for(int n = ; n <= ; ++n) {
int cnt = ;
for(int i = ; i < len; ++i) cnt = mul(cnt, g[n][blocks[i]]);
F[n] = G[n] = cnt;
for(int h = ; h < n; ++h)
F[n] = add(F[n], -mul(F[h], G[n - h]));
if(len & ) ans[n][width] = add(ans[n][width], F[n]);
else ans[n][width] = add(ans[n][width], -F[n]);
}
} else {
search(w + , now + , len);
blocks[len] = now;
search(w + , , len + );
}
} inline void init() {
for(int m = ; m <= ; ++m) {
width = m;
getTransfer(m);
getG(, m);
search(, , );
}
} int n, m;
int main() {
init();
while(scanf("%d%d", &n, &m) == ) printf("%d\n", ans[n][m]);
return ;
}
2016 Multi-University Training Contest 1 I. Solid Dominoes Tilings的更多相关文章
- 2016 Al-Baath University Training Camp Contest-1
2016 Al-Baath University Training Camp Contest-1 A题:http://codeforces.com/gym/101028/problem/A 题意:比赛 ...
- 2016 Al-Baath University Training Camp Contest-1 E
Description ACM-SCPC-2017 is approaching every university is trying to do its best in order to be th ...
- 2016 Al-Baath University Training Camp Contest-1 A
Description Tourist likes competitive programming and he has his own Codeforces account. He particip ...
- 2016 Al-Baath University Training Camp Contest-1 J
Description X is fighting beasts in the forest, in order to have a better chance to survive he's gon ...
- 2016 Al-Baath University Training Camp Contest-1 I
Description It is raining again! Youssef really forgot that there is a chance of rain in March, so h ...
- 2016 Al-Baath University Training Camp Contest-1 H
Description You've possibly heard about 'The Endless River'. However, if not, we are introducing it ...
- 2016 Al-Baath University Training Camp Contest-1 G
Description The forces of evil are about to disappear since our hero is now on top on the tower of e ...
- 2016 Al-Baath University Training Camp Contest-1 F
Description Zaid has two words, a of length between 4 and 1000 and b of length 4 exactly. The word a ...
- 2016 Al-Baath University Training Camp Contest-1 D
Description X is well known artist, no one knows the secrete behind the beautiful paintings of X exc ...
随机推荐
- ubuntu14.04 下安装有道词典
安装步骤 1.ubuntu14.04.1版本下是不能直接安装有道词典的,首先需要把14.04.版升级为14.04.2版. 在终端窗口中输入以下命令: sudo apt-get update sudo ...
- DOM0级事件处理和DOM2级事件处理
转自:http://www.cnblogs.com/holyson/p/3914406.html 0级DOM 分为2个:一是在标签内写onclick事件 二是在JS写onlicke=function ...
- LoadRunner 函数之 web_add_cookie
简单示例: Action() { // 添加cookie web_add_cookie("is_login=True;path=/;domain=10.1.102.75"); // ...
- @SuppressWarnings注解的用法
一.前言 编码时我们总会发现如下变量未被使用的警告提示: 上述代码编译通过且可以运行,但每行前面的"感叹号"就严重阻碍了我们判断该行是否设置的断点了.这时我们可以在方法前添加 @S ...
- MRDS学习二——机械车
准备机械车: 第一步:从Service中选择一个Generic Differential Drive (通用差速驱动:同一轴的左右轮胎可以转动不同速度的车子)放入Diagram中. 第二步:对其进行配 ...
- 关于Azure带宽的测试
以前见客户经常会碰到一些客户问我们你们Azure的带宽是多少,每次回答这个问题我们只能含糊地告诉客户一个大概数值,这样就会留给客户一个认为我们很不专业的印象,其实站在客户的角度我们也能理解,连这样的一 ...
- php 类编写
1.没有重载的函数,实现重载函数只能通过func_get_args()这种方式进行转化 2.每个变量只能单独命名为控制权限(private.protected.public) 3.php反射类带参数 ...
- Hibernate一对一、一对多、多对多注解映射配置
一对一: 一对多: 多对多:
- Python自动化之一对多
一对多 建立一对多关系之后(也就是加了外键),会在字表里面多一个"外键字段_id"这个字段 查询 #_*_coding:utf-8_*_ from django.db import ...
- PHP 打印调试信息
1.将输出的数组存入文件,比如debug_trace()的输出: $debug_info = print_r(debug_backtrace(),true); file_put_contents(&q ...