#P16397. 虫群分解
虫群分解
题目背景
Jessie 有一张矩形网格图,其中每个格子都属于某一条“虫”。她原本想把整张图打印出来,但打印机在按行逐格打印的过程中耗尽了墨水,因此你只能看到打印内容的一个前缀。
已经打印出的字母描述了部分虫的形状:相同字母对应同一条虫,不同字母对应不同的虫;尚未打印的格子使用 ? 表示。请根据这些残缺的信息,计算有多少种完整的虫群分解与之匹配。
题目描述
在方格网格上,一条虫是一个由一个或多个格子组成的序列。除第一个格子外,序列中的每个格子都必须位于前一个格子的正下方或正左方。
一个矩形的虫群分解,是由若干条互不相交的虫组成的集合,并且这些虫所包含的格子恰好覆盖整个矩形。
给定一个矩形 printed,其中:
- 小写英文字母
a到z表示已经打印出的格子; ?表示尚未打印出的格子;- 标有相同字母的所有格子属于同一条虫;
- 标有不同字母的格子属于不同的虫。
打印机按照从上到下、每行从左到右的顺序逐格打印。因此,将所有格子按上述顺序排列后,所有已经打印的字母必定构成该序列的一个前缀,其余格子全部为 ?。
字母只用于描述输入中已经打印出的部分。原始的完整虫群分解可以包含任意多条虫,并不局限于 26 条。
如果两条虫所包含的格子集合不同,则认为它们是不同的虫。如果两个虫群分解所包含的虫集合不同,则认为它们是不同的虫群分解。
请计算所有与 printed 匹配的完整虫群分解数量,并对 (10^9+7) 取模。
输入格式
第一行包含两个整数 (H,W),分别表示矩形的行数和列数。
接下来 (H) 行,每行包含一个长度为 (W) 的字符串,表示 printed。
输出格式
输出一个整数,表示与 printed 匹配的虫群分解数量对 (10^9+7) 取模后的结果。
样例 1
输入
2 2
x?
??
输出
9
解释
打印机只打印出了左上角的一个格子。单独出现的字母 x 不会对虫群分解施加额外限制,因此需要统计整个 (2\times 2) 矩形的所有虫群分解,共有 (9) 种。
样例 2
输入
1 3
???
输出
4
解释
一行三个格子可以组成一条虫、两条虫或三条虫。其中,分成两条虫有两种方法,因此答案为 (4)。
样例 3
输入
5 4
aabb
bbby
bxyy
bxyq
qqqq
输出
1
解释
注意,样例中的 q 是小写英文字母,而不是问号 ?。
所有格子都已经打印,给出的字母恰好描述了一个合法的虫群分解,因此答案为 (1)。
数据范围
- (1\le H\le 50);
- (1\le W\le 50);
- 每一行字符串的长度均为 (W);
- 每个字符均为小写英文字母或
?; - 按照行优先顺序排列所有格子后,所有字母构成一个前缀,所有
?构成一个后缀; - 保证至少存在一种与输入匹配的虫群分解。