论文:《周伟ftfish --- 动态规划之状态压缩》
关键之处在于:
①针对棋盘不同限制用dfs把每行可行的状态压缩表示成一个数存到s[]。
②枚举当前处理行和上一行的状态时根据题目限制判断状态是否互斥。
③有时棋盘上会有些点不能放置,我们也把一行中不能放置的点压缩成一个数存到no[]中,比如用00011000表示第3列和第4列不能放置。然后处理当前行时如果s[j1] & no[i] == 0表示当前放置情况与不能放置的点不冲突。
sgu 223 Little Kings
棋盘限制:在n*n(n<=10)的棋盘上放k个国王(可攻击相邻的8个格子,不能放其他国王),求方案数。
分析:当前行的状态矛盾只涉及到上一行,并且还有放几个国王的限制,所以设dp[i][j][k]表示处理到第i行,第i行状态为j放了k个国王的方案数
dp[i][j][k] = dp[i-1][j'][k-c[j']].
//sgu 223 状态压缩DP 棋盘
#include
#include
#include
#include
#include
#include
#include
#include
#include
hdu 4539 郑厂长系列故事——排兵布阵
棋盘限制:在n*m(n<=100, m<=10)的棋盘上放士兵,每个士兵的曼哈顿距离2的地方都不能放别的士兵。并且有些地方不能放士兵。求最多能放几个士兵。
分析:因为距离为2可能涉及到上2行的状态,所以设dp[i][j1][j2]表示处理到第i行,第i行状态为j1,第i-1行状态为j2最多能放几个士兵。然后因为某些地方不能放置,需要用到③的s[j1] & no[i]。dp[i][j1][j2] = max(dp[i][j1][j2], dp[i-1][j2][j3])
//HDU 4539 状态压缩DP 棋盘
#include
#include
#include
#include
#include
#include
#include
#include
#include
poj 1185 炮兵阵地
棋盘限制:在n*m(n<=100, m<=10)的棋盘上放士兵,每个士兵上下左右2格子内都不能放别的士兵。并且有些地方不能放士兵。求最多能放几个士兵。
分析:和上一题基本一样,就是判断状态互斥时有区别。
//POJ 1185 炮兵阵地 状态压缩DP
#include
#include
#include
#include
#include
#include
#include
#include
#include