2934. 插头DP

给你一个 n×m 的棋盘,有的格子是障碍,问共有多少条回路满足经过每个非障碍格子恰好一次。

image

如图,n=m=4(1,1),(1,2) 是障碍,共有 2 条满足要求的回路。

输入格式

第一行包含两个整数 n,m

接下来 n 行,每行包含一个长度为 m 的字符串,字符串中只包含 *.,其中 * 表示障碍格子,. 表示非障碍格子。

输出格式

输出一个整数,表示满足条件的回路数量。

数据范围

2n,m12

输入样例:

4 4 **.. .... .... ....

输出样例:

2

解题思路

插头dp

插头dp 主要用来解决一些网格图上的哈密顿回路方案的相关问题
本题即 插头dp 模板题,即给出一个网格图,并且要求一些格子不能经过,求哈密顿回路的方案数
做法通常是一格一格做,由于是哈密顿回路,即每个格子会有两条出边(即插头),处理当前格子的时候之前,记录上一行边界出边的状态,通常记录这些的状态有两种方法:

  1. 最小表示法:由于上面每一个出边,一定会对应另外一条出边,对于每一对匹配边,用同一个数字表示,不同对匹配边之间用不同的数字表示,最后所有的这样的数字连起来的最小表示法即为该边界的状态
  2. 括号表示法(效率一般更高,因为可以转化为进制之间的运算):从左往右,如果没有当前边界没有出边则用 0 表示,否则如果该匹配边在左边用 1 表示,在右边用 2 表示,最后会形成 012 这样的数字,但是这样的数字得用四进制表示,原因在于四进制好进行位运算

状态表示:f[i][j][s] 表示处理到 (i,j) 这个格子时边界状态为 s 时得方案数

状态计算:
插头dp 的状态转移一般比较复杂,需要分好多情况讨论(这里采用括号表示法):
image
处理到 (i,j) 这个格子的时候,其左边界插头的状态为 x,上边界插头的状态为 y0x,y2

  1. 如果 (i,j) 是障碍物,则要求 (i,j) 上不能出现插头才是合法状态,即 x=y=0,此时状态不变
  2. 如果 x=y=0,即左边界和上边界都没有插头,因为哈密顿回路要求每一个非障碍物的格子都要有两个插头,且这两个插头是连通的,即一定有一个出去然后另外一个回来,更新状态,由定义:x1,y2
  3. x=0,y0,此时 y 这个插头有两种选择:向下、向右。向右时当前格子的右边界状态即为 y,下边界状态为 0;向下时下边界状态为 y,右边界状态为 0
  4. x0,y=0,同样地,此时 x 这个插头有两种选择:向下、向右。向右时当前格子的有边界状态为 x,下边界状态为 0;向下时下边界状态为 x,右边界状态为 0
  5. x=y=1,此时两个插头连通,当前格子的右、下边界状态都为 0,且右边对应的状态需要修改,即此时两个状态 x,y 都有一个匹配插头,且都在右边,状态都为 2,由于这两个插头已经连通,所以右边之前未匹配的插头开始匹配,即将右边两个匹配的插头的第一个插头状态修改为 1
  6. x=y=2,同理,此时两个插头连通,当前格子的右、下边界状态都为 0,且左边对应的状态需要修改,即此时两个状态 x,y 都有一个匹配插头,且都在左边,状态都为 1,由于这两个插头已经连通,所以左边之前未匹配的插头开始匹配,即将右边两个匹配的插头的第二个插头状态修改为 2
  7. x=2,y=1,此时两个插头连通,当前格子的右、下边界状态都为 0,由于此时两个插头连通,但是对应的匹配的插头正好左边的匹配插头状态为 1,右边的匹配插头状态为 2,所以这时这样的状态不用修改
  8. x=1,y=2,此时两个插头连通,但是对于当前 x 来说,其对应的匹配插头在右边,对于 y 来说,其对应的匹配插头在左边,这样两条路径要么相交,要么重合,由于两条路径相交的话就不再是一条哈密顿回路,所以只能重合,而重合说明当前遍历的格子一定得是最后一个合法的格子

设有效状态数量为 S,则:

  • 时间复杂度:O(n3×S)

代码


__EOF__

本文作者acwing_zyy
本文链接https://www.cnblogs.com/zyyun/p/16978234.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   zyy2001  阅读(98)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示