3.4.1 状态压缩DP
可能在一些DP的递推关系式中,下表不是普通的整数,但是我们可以把它编码成一个整数,或者给它们定义一个全序关系并用二叉搜索树存储,从而可以记忆化搜索来求解。
旅行商问题:
给定一个n个顶点组成的带权有向图的距离矩阵d(I,j)(INF表示没有边)。要求从顶点0出发,经过每个顶点恰好一次后再回到顶点0。问所经过的边的总权值的最小值是多少?
$2\le n \le 15$
$0\le d(i,j) \le 1000$
所有可能的路线共有(n-1)!种,就算此题的n很小也不能列举。
假设现在已经访问过的顶点的集合(起点0当作还未访问过的顶点)为S,当前所在的顶点为v,用dp[s][v]表示从v出发访问剩余所有顶点最终返回顶点0这一段路径的权值总和的最小值,则有如下的递推关系式:
这个递归式中,S是一个集合而不是普通的整数,对于集合我们可以把每一个元素的选取与否对应到一个二进制位里,从而把状态压缩到一个整数。
1 | //输入 |
另外可以不用递归而从全序排列字典序倒叙来循环求解。而像这样针对集合的DP我们一般叫状态压缩DP。
铺砖问题
给定$n\times m$的格子,每个格子被染成了黑色或者白色。现在要用$1\times 2$的砖块覆盖这些格子,要求块与块之间不互相重叠,且覆盖了所有白色的格子,但不覆盖任意一个黑色格子。求一共有多少种覆盖方法,输出方案数对M取余后的结果。
这道题的想法有点难理解昂。
索性不强行理解了,咱们根据代码来理解。
1 |
|