Description

在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。

Input

只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)

Output

方案数。

Sample Input

3 2

Sample Output

16

首先这道题用到了名叫状压dp的算法

首先声明:这篇博客不适用于大神们!!!!!

看到互不侵犯的king这道题首先想到的是八皇后问题,但是发现和八皇后大不一样,因为八皇后是用的深搜的方法,但是由于根据国象的规则,一个棋盘能放的皇后要比国王少得多,所以DFS即可。

所以我们考虑其他的方法,因为国王的攻击范围很小,只有周围的一圈。但我们依然不能把所有的状态推出来(即使n<=9)。但我们可以发现只要确定了第一行,就可以将下面的用动规推出来。这样我们就可以用枚举的方式来做了。在枚举的同时,我们可以用二进制的方式来表示状态,这样较好比较,同时也可以压缩状态,这就是状压dp的思想。在这里可以模拟一下。

比如说n=5。 用1表示该格有国王,0反之。

1 1 1 1 1 这种情况显然是不存在的,我么就要把它排除掉。那么怎么排除呢?我们考虑用位运算的思想。将它 右移(>>)一位(因为国王的攻击范围只有1)。即 1 1 1 1 1再进行(&)运算,这样的返回值是1则出现冲突,再比如这种情况 1 0 1 0 1                                         1 1 1 1 1                                                                。                                1 0 1 0 1   这样的返回值是0,所以这种情况存在。而二进制我们可以直接用一个十进制数来表示。如 1 1 1 1 1 十进制是31,可以试一试计算 31&(31>>1)==1.而 1 0 1 0 1 十进制是21,

21&(21>>1)==0。比较时应该左移、右移都进行。另外我们还可以进行预处理。总状态数为 2^n-1,只进行循环即可,代码如下

int check2(int a)//一行自比
{
if(a&(a<<)) return ;
if(a&(a>>)) return ;
return ;
}
int get(int x)//计算状态为x,其中 1 的个数。
{
int tot=;
while(x){
if(x&)
tot++;
x=x>>;
}
return tot;
}int tot=(<<n)-;
for(int i=;i<=tot;i++)
if(check2(i)){
zt[++num]=i;//状态
gs[num]=get(i);//该状态含的国王的个数
}

接下来讲dp的过程——

int f[10] (i) [600] (j) [82] (k) {0};//i为行数,j为第j种状态,k为当前总国王数 f[i][j][k]表示第i行状态为第j种放置了k个国王的方案数。

另外的一种预处理如下,对比两行的状态,可以加速dp过程中的比较。

int check1(int a,int b)//两行对比
{
if(a&(b<<)) return ;
if(a&(b>>)) return ;
if(a&b)return ;//对比两行时就需要对比不移动时的状态,至于为什么,自行脑补
return ;
}
for(int i=;i<=num;i++)//pd[i][j]==1则表示i在上一行j在下一行,并且不冲突
for(int j=;j<=num;j++)
if(check1(zt[i],zt[j]))
pd[i][j]=pd[j][i]=;

主要的dp过程如下

for(int i=;i<n;i++)//循环行数,对应f数组中的行数(i)
for(int j=;j<=num;j++)//循环状态,对应f数组中的(j)
for(int k=;k<=m;k++)//循环国王数,对应数组中的(k)
if(f[i][j][k])
for(int q=;q<=num;q++)//循环i下一行的状态
if(pd[j][q]&&(k+gs[q]<=m))//满足条件就继续
f[i+][q][k+gs[q]]+=f[i][j][k];
long long int ans=;
for(int i=;i<=num;i++)//把第n行的所有状态的f值相加即为答案
ans+=f[n][i][m];

这就是主要的函数,其他的自己加上的吧,光复制标程是没有意义的!!

注意:f[0][1][0]=1  即初始的状态。

BZOJ 1087 互不侵犯king的更多相关文章

  1. BZOJ 1087 互不侵犯King 状态压缩DP

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1087 题目大意; 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国 ...

  2. BZOJ 1087 互不侵犯King (位运算)

    题解:首先,这道题可以用位运算来表示每一行的状态,同八皇后的搜索方法,然后对于限制条件不相互攻击,则只需将新加入的一行左右移动与上一行相&,若是0则互不攻击,方案可行.对于每种方案,则用递推来 ...

  3. BZOJ 1087 互不侵犯

    Description 在\(N \times N\)的棋盘里面放\(K\)个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共\(8 ...

  4. BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3336  Solved: 1936[Submit][ ...

  5. bzoj 1087 [SCOI2005]互不侵犯King 状态压缩dp

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MB[Submit][Status][Discuss] Descripti ...

  6. BZOJ 1087:[SCOI2005]互不侵犯King(状压DP)

    [SCOI2005]互不侵犯King [题目描述] 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子 ...

  7. 1087: [SCOI2005]互不侵犯King

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4276  Solved: 2471[Submit][ ...

  8. 【状压dp】互不侵犯KING

    互不侵犯KING Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3866  Solved: 2264[Submit][Status][Discuss] ...

  9. BZOJ-1087 互不侵犯King 状压DP+DFS预处理

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2337 Solved: 1366 [Submit][ ...

随机推荐

  1. JS实现用键盘控制DIV上下左右+放大缩小与变色

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. UVA 806 Spatial Structures

    题意: 如果某一大区域所有色块颜色是相同的,那么这一个大区域就算作一块,如果不同,则将其划分成四个小区域,然后重复上述步骤递归进行直到所有区域的颜色相同为止.然后根据上面划分的区域建树,小区域作为大区 ...

  3. IIS应用程序池自动回收问题的有效解决办法

    问题:Timer不能持续执行,如果长时间没有访问,就会被IIs自动回收.造成一些定时作业无法完成. 解决方式1:改用windows服务或是winform方式 解决方式2:在Application_En ...

  4. Node.js服务的重启与监控

    开始:Node +服务文件名 停止:直接快捷键Ctrl+C 监控:1.安装 npm install supervisor -g, 2.supervisor app.js 参考:http://blog. ...

  5. mysql优化(1) 观察服务器周期性变化

    先把nginx和memcached环境开启 /usr/local/nginx/sbin/nginx /usr/local/fastphp/sbin/php-fpm /usr/local/memcach ...

  6. HTML5新属性

    1.contenteditable 属性指定元素内容是否可编辑. 注意: 当元素中没有设置 contenteditable 属性时,元素将从父元素继承. 所有主流浏览器都支持 contentedita ...

  7. 前端开发面试题收集 JS

    前端开发面试题收集-JS篇 收集经典的前端开发面试题 setTimeout的时间定义为0有什么用? javascript引擎是单线程处理任务的,它把任务放在队列中,不会同步执行,必须在完成一个任务后才 ...

  8. 远程连接mysql数据慢的问题

    由于公司没有服务器,买的阿里云的服务器用于开发,所以就在本地连接服务器的mysql. 连接很慢,打开表也很慢,一开始没多想,以为是网络慢而已. 最近,开发经常要使用navicat连接数据库,实在是太慢 ...

  9. debian install & configure(2)-drivers-nvidia

    ==========================================手动编译卸载受限驱动 :apt-get --purge remove nvidia-*apt-get --purge ...

  10. Visual Studio Code和Docker开发asp.net core和mysql应用

    Visual Studio Code和Docker开发asp.net core和mysql应用 .net猿遇到了小鲸鱼,觉得越来越兴奋.本来.net猿只是在透过家里那田子窗看外面的世界,但是看着海峡对 ...