题意
给出 n×m的矩形方块,可以往上面铺1×2的砖块,问铺满这个方块的方案有多少种。
题解
砖块可以竖铺和横铺,竖铺的话会影响到下一行,横铺的话不会影响到下一行,这里我们令 1
:表示该方块不会影响下一行,0
:表示该方块会影响下一行。
条件一:
考虑(i.j)
这一格,如果(i-1,j)
上是0
,那说明(i-1,j)
是竖铺的砖块,那么(i,j)
便是1
,该点不会影响到下一行了。若(i-1,j)
是1
,那么(i,j)
可以是0
也可以是1
。从而可以得知(i,j) | (i-1,j) = 1
。
条件二:
只有这个条件还是不够的,因为一旦(i-1,j)
是横铺的话,那么(i-1,j+1)
也是1
,现在考虑初始状态,001100
,因为第一行是不会有上一行影响他的,所以如果该点时1
那么其必定是横铺。根据横铺的性质,必定有两个连续的1
,所以我们可以得出第一行合法的状态有哪些。例如010101
便是不合法的。
得出了第一行合法的状态后,枚举第二行的状态,首先要满足的便是条件一,其次考虑条件二,因为第二行是会受上一行影响的,所以如果第二行出现(i,j)
出现1
那不一定是横铺的砖块,因为如果上一行是(i-1,j)
是0
的话,那么(i,j)
已经被覆盖了且不会影响下一行。
仔细观察的话可以发现。如果(i-1,j)
是1
同时(i,j)
也是1
的话那么该处一定是横铺。所以只需两行状态相与(&)为1
的点便是横铺,然后便可以判断是否合法(这里有个优化的地方,便是可以预处理出合法的状态有哪些)。
最终一行的答案必须全是1
,因为其没有下一行可以影响了。
代码
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
int n,m,mark[1