最近学习了状压DP,将一些思路与心得总结一下。
首先看这样一个问题,对于一个N*N(N<=8)的棋盘,我们考虑在这个棋盘上放置N个皇后,每一个皇后只能控制它所在的行和列,我们希望皇后之间不要冲突,问有几种放置方案。
解决这个问题有很多种方法,最简单的就是用上一点组合数学知识,轻松得出结果为N!
对这个问题进行修改,现在棋盘上出现了一些黑格,在这些黑色格子上不允许放置皇后,问有几种方法?另外,这里改变数据(N<=20) ,首先,我们需要清楚,这个数据范围已经不允许我们爆搜了,我们需要用其他办法解决这一问题。首先我们自然想象到动态规划,我们按行处理,当前这一行能放置皇后的位置与之前放置的皇后的位置有关,如果之前皇后放在了当前行黑格子所在的列,我们能够放置的位置要比之前没有放置到黑格子所在的列的方案要多。 既然之前的放置会影响当前的放置,我们应该怎样处理呢?
这样就引出了今天所要说的状压DP。
我们用一个二维数组dp[i][st] 表示前i行放置状态为st时的方案数 而怎样处理st呢 ?我们就需要用一个二进制串从左到右来表示第j列是否放置了皇后,具体代码如下
for(int i=1; i<=n; i++) for(int st=0; st<=(1<<n)-1; st++) for(int j=1; j<=n; j++) { if(mp[i][j] && (st&(1<<j-1))==0) {
t=st+(1<<j-1);
f[i][t]+=f[i-1][st];
}
复杂度O(n^2*2^n)
例题:TSP 旅行商问题
国王游戏