1 条题解
-
0
题意回顾
- 给定 的网格, 个位置是洞(缺失格)。
- 使用无限个 L 形三联牌(占 3 格,形状如
L,可旋转 90° 的倍数)密铺。 - 要求:
- 覆盖所有非缺失格
- 不重叠、不出界、不覆盖缺失格
- 判断是否可行。
初步分析
1. 必要条件
- 非缺失格数量 必须是 3 的倍数,否则直接输出
NO。 - 当 或 时,L 形三联牌无法铺(因为 L 形至少需要 2×2 的空间才能放一个牌),但数据范围中 ,所以不用考虑 1 维情况。
核心思路
本题 很小(最大 13), 很大(最大 ), 最多 250。
采用 按行状压DP + 矩阵快速幂 的方法。
2. 状态定义
我们按 列 来定义状态(因为 ,状态数 可接受):
设 表示处理到第 列时,当前列的覆盖状态为 (1 表示该格已被覆盖,0 表示未覆盖)的方案是否可行。但更常见的做法是 按轮廓线DP(插头DP)来考虑,这里我们采用 按列递推,用二进制表示当前行和下一行的覆盖需求。
实际上更简单且经典的做法是:
状态: 表示当前处理到第 行,且该行的覆盖情况由集合 表示( 是 位的二进制数,1 表示该格还未被覆盖,0 表示已被覆盖)。
转移时,我们要用 L 形牌覆盖第 行中还未覆盖的格子,并且可以延伸到第 行。
3. 转移方法
从 (当前行未覆盖集合)转移到 (下一行未覆盖集合):
我们枚举所有可能的 L 形牌放置方式,这些牌必须覆盖 中的一些格子,并且可能覆盖第 行的一些格子(这些格子在 中为 1 表示仍未被覆盖)。
具体来说,L 形三联牌的形态有四种(旋转 90° 倍数):
##
###
##
###
##
其中
#表示占用的格子。
我们 DFS 枚举当前行 中最左的未覆盖格,尝试用四种形态之一覆盖它,并更新 和 。
4. 矩阵化与快速幂
如果 (无缺失格),那么状态转移是 齐次 的,即从 到 的可行性是固定的,与行号无关。
我们可以构建一个 的布尔矩阵 ,其中 表示状态 可以转移到状态 。
初始状态:(第 0 行时,所有格都未被覆盖,但第 0 行之前不存在,所以是空状态)。
最终状态:(最后一行之后,所有格都应被覆盖)。
那么问题转化为: 的 项是否为 1。
5. 处理缺失格
当 时,矩阵 不是完全齐次的,因为某些行有缺失格。
我们可以将 行按缺失格所在的行号 分段,每段内没有缺失格,使用矩阵快速幂;在缺失格所在行,特殊处理转移(禁止覆盖缺失格)。
具体做法:
- 将缺失格按 坐标排序,将 分成若干段 。
- 对每一段 ,长度 ,用矩阵 转移。
- 在缺失格所在行 ,我们修改转移矩阵:禁止覆盖缺失格对应的列。
6. 对小 的特判
- 时,必须 且 才可能(实际上 时 L 形三联牌无法铺满,需要具体构造验证)。
- 时,也有特殊模式。
算法步骤
- 如果 ,输出
NO。 - 对缺失格按 排序,分段处理。
- 预处理无缺失格时的转移矩阵 (通过 DFS 枚举所有可能的 L 形牌放置方式)。
- 对每一段 :
- 用快速幂计算
- 更新 DP 状态向量
- 在缺失格行,特殊处理:只允许不覆盖缺失格的转移。
- 最终检查 (全 0 状态)是否可达。
复杂度分析
- 状态数 。
- 矩阵乘法 但 ,可能较慢,需要优化(用布尔矩阵+位运算)。
- 快速幂 次矩阵乘法。
- 总复杂度 ,在 时勉强可行(需要优化)。
样例验证
样例 1
缺失格:(1,1), (1,3), (4,3)
非缺失格数 ,是 3 的倍数。
可以构造铺法,输出YES。样例 2
非缺失格 ,是 3 的倍数,但实际无法铺,输出NO。样例 3
非缺失格 6,是 3 的倍数,可以铺,输出YES。
总结
本题是 状压DP + 矩阵快速幂 的经典题,难点在于:
- 状态定义与 L 形牌覆盖的转移枚举
- 大 时用矩阵快速幂加速
- 缺失格的分段处理
通过合理的状态设计和矩阵优化,可以在规定时间内解决问题。
- 1
信息
- ID
- 3608
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 12
- 已通过
- 1
- 上传者