状态压缩DP
题目
思路
1. 状态压缩题目数据量在某一维度会比较小, 当看到二维数组的某一行或某一列比较短时, 就应该想到状态压缩. 一般来讲, 用 PUSH 操作更多
2. 第一题 棋盘问题. 每一行每一列只能放一个棋子. dp[i][state] 表示前 i 行放棋子后得到的状态为 state 时的方案数. dp[i][state] = sum(dp[i-1][oldstate])
3. 第二题 炮兵阵地. 每一行能够安放的炮台数是一定的. 一门大炮的攻击范围为 2, 所以状态需要记录前两行的. dp[i][s1][s2] 表示第 i 行安防炮台在 s1 处第 i-1 行安放炮台在 s2 处 时的总炮台数
dp[i][s1][s2] = funct(dp[i-1][s2][s3]) 其中 s1 和 s3 不能有交集
4. 第三题 涂色问题. N 不大于 15, 明显就是个状态压缩题. 状态 state 表示第 i 个方块有没有被涂色, 共有 (1<<15) 中可能性.
dp[state][i] 表示给第 i 个方块涂色后, 状态为 state 时的最小拿笔数
dp[newState][i] = min(dp[oldState][j] + 1) if color[j] != color[i]
= min(dp[oldState][j] ) if color[j] == color[i]
PUSH 更新, 合情合理
5. 第四题 搬家问题. 先计算所有的状态中能被两辆车一次搬走的集合. 对这些集合进行 01 背包
dp[i][state] 表示状态集中的前 i 个状态到达 state 时需要搬几次
dp[i][state] = dp[i-1][oldstate] + 1 其中 oldstate = state-state[i] (PULL 更新, 减法不易实现)
dp[i][s[i]|state] = dp[state] + 1
空间可以降低到一维