3253【CQOI2015】标识设计
问题描述
一家名字缩写为LLL的公司正在设计logo,他们的初步方案是在一张方格上放置3个L形的图案以及一些额外的装饰性图形。例如:
(灰色区域表示装饰性图形)
3个L图案和装饰性图形均放置在方格之中,且必须占满方格。"L"的横竖笔画长短均可,但长度必须大于0(即不能退化为一条线段)。另外,为了使L图案醒目且容易辨别,设计师规定3个L形图案之间不能有重叠或交叉的部分。当然,L形图案也不能穿过装饰图形或与之重叠。
现在设计师已经确定了所有装饰性图形的位置,希望你计算一下放置不同的L形图案总共可以设计出多少个logo。
输入格式
输入文件第一行包含两个空格分开的正整数n和m,分别表示方格的行数和列数。
接下来n行,每行m个字符,为"."或"#"。"#"表示该方格为装饰性图形,"."表示可以放置L图案的空白区域。
输出格式
输出一个整数,为可能的logo总数。
样例输入
4 4
....
#...
....
..#.
样例输出
样例输出
4
提示
样例解释:
满足要求的logo只有这4种。注意,颜色只是为了便于说明,不影响方案数,因为在实际的logo中3个L图案将使用相同的色彩、纹理和光泽。
数据范围:
对于30%的数据,n,m≤5。
对于100%的数据,2≤n,m≤30。
首先,根据题意很容易想到利用DP来求解,那么问题在于如何确定状态。
我们可以将这三个“L”型的标记看成三条路径,然后问题就变成求三条互不相交的“L”型的路径。
观察“L”的特点我们发现,相当于是我在拓展这条路的时候只能向下或向右走,于是我们可以列出如下状态:
$F[x][y][re][s][ty]$
我们来解释一下这个状态,他表示的是我当前讨论到了(x,y)这个格子,还剩下re个“L”没有放,然后s是一个状压的结果,他表示在二进制下,当前在某些列存在向下走的路径,但还没有开始向右走,ty表示当前是否有路径正在向右走。
由于可能的转移只能是路径向下或向右延伸,因此我们可以推出转移方式(以下可以直接看代码):
若当前格子在一条向下走的路径上,那么他有向下和向右两种转移。
若当前格子在一条向右走的路径上,那么他有向右和停止两种转移。
若当前格子不在路径上,并且res>0&&y≠m,那么他可以作为一条路径的起点。
若当前格子是障碍格,并且处在一条路径上,那么返回0。
若当前格子同时在一条向右走的路径和向下走的路径上,那么返回0。
若当前y>m,跳到下一行。
若当前x>n,但还有“L”没放或者还有路径在向下走,那么返回0,否则返回1。
从上到下,从左到右,逐行逐列DP即可。
最后我们来看看s表示的状态,由于我们最多只需要放3个“L”,那么我们最多同时存在三列有向下走的路径,因此s的状态总数的最大值等于4525种,貌似还没有这么多,忽略。因此我们可以提前离散化。
于是我们可以用记忆化搜索的形式来写,具体情况参见代码。
代码写的很渣,亟待改进
1 |
|