新生研讨课上面提到了哈米尔顿回路,今天就学了一下哈密顿回路。
给定一张无向图,由指定的起点前往指定的终点,途中经过所有其他节点且只经过一次。
而今天看的是四联通下的图的哈密顿回路计数。哈密顿回路是一个NP-hard问题,没有多项式算法意味着我们只能对其进行搜索和剪枝,直接搜索显然是一个N!级别的算法,中间包含了太多无效的解。这意味着我们要缩小解的空间,
四联通,若图的大小为n*m,我们去假设每一个格子是怎么去放上穿过他的路径的。显然当我们铺上了k*m时,此时能影响接下去的只有最后铺上的m个元素会影响解,也就是说我们发现他是一个没有后效性的计数问题。那不妨把状态设计为dp[i][j][opt]表示铺到第i行第j列前m个元素的状态,那么我们如何去表示m个格点中元素的状态呢。这时我们就要引概念。
1.插头
一个格子某个方向的插头存在表示这个格子在这个方向与相邻格子相连.
2.轮廓线
已决策格子和未决策格子的分界线
这时有一个简单的显而易见的结论轮廓线上方与其相连的 有n+1个插头,包括n个 下插头和1个右插头。
状态变成了f (i, j, S) 表示转移完(i, j) ,轮廓线上从左到右n+1个插头是否存在以及它们的连通性为S的方案总数.
回到了连通性的表示上,cdq在她的国家集训队论文《基于连通性的状态压缩动态规划问题》中给出了插头的最小表示法。
结论如下
1,每个非障碍格子恰好有2个插头
2.轮廓线以上由若干条互不相交的路径构成
3.从左到右一定不会出现4个插头a, b, c, d,a, c匹配,b, d匹配.
于是插头不会交叉,且两两匹配,就联想到了括号序列,用左右括号来表示插头的类型
0表示无插头,1表示左插头,2表示右插头。
考虑转移:每次转移相当于轮廓线上当前决策格子的左插头改成下插头,上插头改成右插头的状态.
第一种情况每次转移相当于轮廓线上当前决策格子的左插头改成下插头,上插头改成右插头的状态.
第二种情况有上插头和左插头,这种情况下相当于合并两个连通分量
第三种情况上插头和左插头恰好有一个,这种情况相当于延续原来的连通分量
对于每种情况再分别讨论细节即可得到转移,时间复杂度n*m*3^n。