一类棋盘互不攻击问题
2008-10-08 21:03 老博客哈 阅读(2855) 评论(11) 编辑 收藏 举报一类棋盘互不攻击问题
农夫三拳@seu(drizzlecrj@gmail.com)
最近在SGU上做了一些棋盘上互不攻击的题目,稍稍的总结一下:
1. SGU 220 Little Bishops 以及 SGU 221 Big Bishops
问题: 求n*n的棋盘上放置k个互不攻击的象的个数。
解法: 将棋盘旋转45度之后,转换成二维动态规划求解。具体参见 黑书243~244页
转移的方程为 F(i,j) = F(i - 1, j) + F(i - 1, j - 1) * (Ri - j + 1)
其中F(i,j)表示前i行放置j个象的总数,Ri表示第i行的格子总数。那么显然F(i - 1, j)就是第i行不放任何象,F(i - 1, j - 1) * (Ri - j + 1)表示第i行放置1个象的情况。
问题: 求n*n的棋盘上放置k个互不攻击的车的个数。
解法: 组合公式,挑选k个行C(n,k),挑选k个列的排列A(n,k),所以总数为C(n,k)*A(n,k)
问题: 求n*n的棋盘上放置k个互不攻击的王的个数。
解法: 状态压缩动态规划。dfs预处理两行之间的转移状态。
方程为: F(i, j2, k) = Sigma{F(i - 1, j1, k - ONE(j2))}
F(i,j2,k)表示第i行状态为j,前i行放置k个王的总数, F(i - 1, j1, k - ONE(j2)) 为第i - 1行状态为j1(且j1和j2可以转移),前i - 1行放置 k - ONE(j2)个王的总数。
显然ONE(j2)为第i行放置的王的个数。
问题: 求n*n的棋盘上放置k个互不攻击的后的个数。
解法: 参加我的这篇文章 《K皇后问题》
问题: 求n*n的棋盘上放置k个互不攻击的马的个数。
解法: 我的解法还做得不好,用的是和3中提到的相同的方法,不过时间复杂度太高了,貌似只能打表交。
我是用F(i,j2,j1,k)表示第i行状态为j2,第i-1行状态为j1,前i行放置k个马的总数,那么有
F(i,j2,j1,k) = Sigma{F(i-1,j1,j0,k - One(j2))} j0和j1能够转移到j2
不知道有没有更好的解法,希望过路大牛指教下。
小结:
对于在棋盘上放置棋子互不攻击的问题,如果问最值问题,例如:n*n的棋盘上最多能够放多少个互不攻击得象等等,问题通常可以转换为二分图模型来求解。
而对于更加通用的n*n棋盘上放置k个互不攻击的棋子的问题,我知道的做法有两种,一种是用容斥原理,另外一种就是状态压缩。其中后者更加通用一些。
欢迎指教!