1 条题解
-
0
题意理解
在 的网格中,有障碍格 # 和空格 .。 要求用恰好三个互不相交的 形块(每个 形占 的子方格中的 个格子,且不能是直线形)铺满所有空格,且 形之间、 形与障碍之间不能重叠。 求方案数。
关键思路
1. 形的表示
每个 形可以看作一个 方块去掉一个格子。 在插头 DP 中,我们用括号表示法(轮廓线 DP)来记录连通性,并用状态记录当前已放置的 形数量。
2. 插头 DP 状态设计
设 表示当前处理到某个格子,轮廓线状态为 ,已经放置了 个 形时的方案数。
用四进制表示每列的插头类型:
:无插头
: 形的左括号(开始)
: 形的右括号(结束)
表示已放置的 形数量。
3. 状态转移
设当前格子 ,轮廓线上对应位置 (当前列)和 (下一列)的插头状态。
情况 1:障碍格
如果 (障碍):
必须 才能转移,保持状态不变。
情况 2:空格且无插头 ()
不放 形:保持状态。
如果 ,可以在此开始一个新的 形:将 设为 。
情况 3:空格且
表示上一行此列有 形开始,现在可以:
向右延伸:将 改为 (结束)。
向下延伸:将 设为 , 设为 。
情况 4:空格且
如果 :可以向右结束:将 设为 , 设为 。
如果 :可以向下结束:将 设为 ;或者向右继续:将 设为 , 设为 。
4. 换行处理
每行结束时,轮廓线状态左移 位(因为列数增加一个虚拟列),并检查最后一列不能有未匹配的左括号()。
5. 最终条件
当处理完最后一行 ,且轮廓线状态 (所有插头匹配完毕),且 (恰好三个 形)时,累加方案数。
算法复杂度
状态数:( 但有效状态很少) 使用滚动数组 + HashMap 存储状态,实际可运行。
代码关键函数
gw(s, i):获取状态 中第 列的插头值( 位四进制)。
sw(s, i, w):将状态 中第 列设为 。
使用 map<pair<ll, int>, ll> 作 DP 表,第一维是 ,第二维是方案数。
总结
本题是带数量限制的插头 DP,通过四进制状态表示 形的连通分量,并限制 形数量不超过 ,最终要求铺满且数量恰好为 。 这是一种经典的骨牌覆盖变种,适合用轮廓线 DP 解决。
- 1
信息
- ID
- 4929
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者