状压DP【p1896】[SCOI2005]互不侵犯
2018-10-15 19:31
357 查看
Description
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。
Input
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
Output
所得的方案数
很明显\(N \leq 9\)状压DP啊 qwq.
这里有限制,我们只能放\(K\)个国王,并且如果一个格子有国王,其周围八个格子都不能放.
设状态\(f[i][j][k]\)代表前\(i\)行中第\(i\)行为\(j\)状态下共放了\(k\)个国王的方案数.
状态转移的话,我们当前行显然已经放了国王.
因此,转移可以很容易想到.
\[
f[i][j][l+calc(j)]+=f[i-1][k][l]
\]
其中\(l\)为枚举的上一行所放的国王的个数,\(k\)为枚举的上一行的状态,\(calc(j)\)为计算\(j\)状态下有多少个国王被放置.
判断合法与否的话,只需要判断一下当前\(j\)状态与\(k\)状态\(&\)起来是否为零。
如何判断状态合法
判断是否\(j\)状态的某一位置右上方有无国王.
\[
(j>>1)&k==0
\]
同理左上方
\[
(j<<1)&k==0
\]
正上方
\[
j&k==0
\]
这几个方向是相对而言的.且我们从第\(1\)行到第\(n\)行放置的话,每次判断是否合法达到了判断6个方向的效果.
判断左右两侧当然是最简单的了
\[
j&(j>>1)==0\ \ && \ \ j&(j<<1)==0
\]
代码
#include<cstdio> #define int long long #define R register using namespace std; int n,m,f[10][2048][108]; int lim,ans; inline bool ok(int i) { return ((i&(i<<1))==0 and (i&(i>>1))==0); }//相邻方向. inline int calc(int x) { int res=0; for(R int i=0;(1<<i)<=x;i++) res+=(bool)(x&(1<<i)); return res; } signed main() { scanf("%lld%lld",&n,&m); f[0][0][0]=1; lim=(1<<n)-1; for(R int i=1;i<=n;i++) { for(R int j=0;j<=lim;j++) { if(!ok(j))continue; for(R int k=0;k<=lim;k++) { if(!ok(k))continue; if((j&k)==0 and ((j<<1)&k)==0 and ((j>>1)&k)==0) { R int now=calc(j); for(R int l=0;l<=m;l++) f[i][j][l+now]+=f[i-1][k][l]; } } } } for(R int i=0;i<=lim;i++) ans+=f [i][m]; printf("%lld\n",ans); }
可以滚动数组滚掉第\(1\)维,切在枚举\(l\)的时候,第三维可能会超内存,因此要开大一点.当然也可以判断一下\(l+now \leq m\)
相关文章推荐
- bzoj 1087: [SCOI2005]互不侵犯King 状压dp
- 洛谷P1896 [SCOI2005]互不侵犯King
- 【bzoj1087】[SCOI2005]互不侵犯King 状压DP
- [BZOJ1087][SCOI2005]互不侵犯King(状压dp)
- [Bzoj1083][SCOI2005]互不侵犯king(状压dp)
- bzoj 1087 [SCOI2005]互不侵犯King 状态压缩dp
- BZOJ 状态压缩dp 1087: [SCOI2005]互不侵犯King
- 洛谷 P1896 [SCOI2005]互不侵犯King
- [bzoj1087][SCOI2005]互不侵犯King【dp】
- [BZOJ 1087][SCOI2005]互不侵犯King:状态压缩DP
- 洛谷 P1896 [SCOI2005]互不侵犯King
- P1896 [SCOI2005]互不侵犯King
- BZOJ 1087 SCOI2005 互不侵犯King 状压DP
- scoi2005 互不侵犯 (状压dp)
- BZOJ1087: [SCOI2005]互不侵犯King 题解【DP】【状压】
- Bzoj 1087: [SCOI2005]互不侵犯King(状压DP)
- bzoj1087 [SCOI2005]互不侵犯King(状压dp)
- 【BZOJ1087】【SCOI2005】互不侵犯King(状压dp)
- 洛谷P1896 [SCOI2005]互不侵犯King
- 洛谷 P1896 [SCOI2005]互不侵犯King(bzoj P1087 [SCOI2005]互不侵犯King)