分析
棋盘型状态压缩一般都是用二进制数来表示当前行的状态,进而实现”压缩”的目的。一般要考虑行内约束和行间约束。
① 状态表示
- 如果当前行只受前一行的约束:
那么我们就只用用一维来表示当前行的状态,然后枚举上一行的状态转移到当前行的状态即可,比如小国王、玉米田、蒙德里安的梦想 - 如果当前行受前两行的约束:
那么我们就需要用两维来分别表示当前行和前一行的状态,然后枚举前两行来转移,比如炮兵阵地、国际象棋 - 如果有数量限制:
比如要求我们只能在棋盘上放多少个该物品,我们就还需要用一维来表示累计到当前行已经放了多少个该物品,比如小国王、国际象棋
② 行内约束
一般情况下是存在行内约束的,比如不能存在相邻两个1,但是也有行内不存在约束的,要仔细辨别,比如蒙德里安的梦想行内就是没有限制的。
$Ps$: 不能有连续1的判断方法
bool check(int x)
{
return !(x & x >> 1);
}
③ 行间约束
行间约束通常考虑两行的同一列不能同时有1,或者两行相邻两行不能同时有1(炮兵阵地)。
$Ps$:
两行同一列不能同时有1: 直接判断$cur$&$pre$不能为1即可
相邻两列不能同时有1:直接判断($cur$<<$1$)&$pre$不能为1即可
特殊情况:
比如像蒙德里安的梦想当前行会受到上一行的影响,上一行也会受到当前行的影响,所以考虑的时候不能单独考虑某一行,要结合起来考虑