状态压缩动态规划
使用场景
如果在动态规划分析状态的过程中,有非长多的状态,可以考虑使用状态压缩动态规划。
一般在棋盘类动态规划中比较常见。
为什么需要状态压缩
在写动态规划的时候,唯一确定状态需要几个维度,就会写几维的dp数组。
举例:
对于两列的方块区域,如果需要表示每行的每个方格是否放了物品,正常情况下是这么写的:
第1列 | 第2列 | |
---|---|---|
第1行 | 🐮 | 🐮 |
... | ... | ... |
第i行 | 🐮/🐘 | 🐮/🐘 |
当前第1行的状态是:
dp[1][1][1]:表示第1行的第1列,第1列都放了物品。
...
所以,对于第i行,一共有如下的4种状态状态:
dp[i][0][0],dp[i][1][0], dp[i][0][1] ,dp[i][1][1]
上面是2列的情况。
如果有很多列,需要如何表示状态?
如果使用n+1维的数组,空间会超出。
所以使用另一种办法来表示这个状态。
就有了状态压缩。
状态压缩举例
在二进制中,每一位都有0/1两个数字,所以可以使用二进制来整体表示当前行的状态。
例如对于第i行:
√ | √ | × | × | √ |
---|
使用1表示√,0表示×:
11001
转为10进制为25.
所以当前行的状态可以用二维数组:dp[i][25]来表示。
将列的所有状态由二进制来表示,再将二进制转十进制,用于dp数组中,作为当前行的某一个状态。
练习题目
poj 1185
题目解析:
Poj 1185 java实现--状态压缩 - Monstro - 博客园 (cnblogs.com)
Poj 1185 java实现--状态压缩 - MonstroのBlog (reclusiveone.com)
poj 3254
题目解析:
POJ P3254 Java实现 - Monstro - 博客园 (cnblogs.com)
POJ P3254 Java实现 - MonstroのBlog (reclusiveone.com)
洛谷 1896
HDU 1074 Doing Homework