1896 [SCOI2005]互不侵犯King

【问题描述】在n*n(1<=n<=10)的棋盘上放k(0<=k<=n*n)个国王(可攻击相邻的8 个格子),求使它们无法互相攻击的方案总数。

【输入格式】输入有多组方案,每组数据只有一行为两个整数n和k。

【输出格式】每组数据一行为方案总数,若不能够放置则输出0。

【问题分析】

由问题很容易联想起经典的“八皇后”问题,似乎就是“皇后”变成了“国王”,而且格子范围似乎也差不多,所求问题也一样。那么这个问题也能用搜索解决吗?

可稍加分析可知搜索是很难胜任的,因为国王的数目可以是很大,加上它与“八皇后”问题的一个本质上的不同便是每个国王只影响周围的一个格子,所以剪枝条件也很少,指数级别的搜索是无法在时限内出解的。

那么一般的动态规划能解决吗?典型的二维DP,F[I,J]似乎无法很好地把状态表示出来,因此我们只能考虑状态压缩的动态规划。

首先我们要注意到这题的关键——每个国王只影响周围八个方向的一个格子,它虽然否定了搜索,却给状态压缩带来了无限生机!

我们改变之前动态规划的思维方式,一行一行地摆放国王,当我们摆放第I行时,这一行只会和前后一行的互相影响,而这一行的状态是可以由我们确定的。那是否可以把一行当作一个整体,然后像传统的动态规划那样进行处理呢?让我们试一下。

每一行它对下一行的影响就体现在这一行的摆放方式以及之前总共放了多少个国王。所以我们可以把摆放方式作为状态,设f[i,j,s]表示第i行状态为a[j]且前i行已放s个国王的方案总数。这样很容易便得到了一个粗略的方程:

 F[i,j,S]=∑F[i-1,k,T]

a[j],a[k]分别表示一种摆放方式,F[i,j]表示第i行用a[j]的摆放方式,且a[j]与a[k]相兼容。并且S等于T加上a[j]这种方式在这一行放置的国王数。

很明显这个方程是没有后效性的,可关键就在于j,k怎么在计算机上表示出来,这就需要我们的主题:状态压缩

看图便知,每一个格子只有两种状态,放和不放,并且注意到格子宽度最大为9。由这便想到了熟悉的二进制表示法。每一个格子对应一个二进制位。这样每一行便对应一个N位的二进制数,如下图所示:

1   0   0   0   1   0   0   0

即十进制的128+8=136

这样我们就可以把一种摆放方式转化为一个数,这样上面方程中的J,K就可以用数字来代替。我们就把一行的摆放方式作为状态,并把它压缩成了一个数!具体的算法流程如下:

①对于每一行,我们通过搜索得出一个合法状态。

②然后再枚举上一行与这一行相容的状态再累加即可,状态用N位的二进制数表示,最大仅为512,所以一个512*9*81的数组就可以了,还可以用滚动数组的技巧。空间是肯定可以承受的。

而一个粗略的时间复杂度:O(K*N*2^N*2^N),似乎大了点。不过注意到由于国王是不能相邻放置的。所以我们可以用一个f(n)来表示当列数为n时每一行可能的放置总数。则f(n)=f(n-1)+f(n-2)初始值:f(1)=2,f(2)=3。

则f(9)=89。因此最大也才是9*89*89*81≈6000000。是可以承受的。

压缩行,有king是1,没有是0.
判断可行,就是将上一行与这一行按位与,接着左移,右移。
剩下的就是简单的dp了。

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int N=;
int n,k,a[],b[],tp;
long long f[N][N*N][<<N],ans;
//第i行,一共摆放了j个king,第i行的摆放情况是g
void dfs(int num,int lst,int at,int bt)
{
if(num==n)
{
++tp;
a[tp]=at;
b[tp]=bt;
return ;
}
dfs(num+,lst,at,bt);
if(num-lst>=)
{
at|=(<<num);
bt++;
dfs(num+,num,at,bt);
}
}
int main()
{
scanf("%d%d",&n,&k);
dfs(,-,,);
f[][][]=;
int end=(<<n)-;
for(int i=;i<=n;i++)
for(int j=;j<=k;j++)
for(int g=;g<=end;g++)
if(f[i-][j][g]>)
for(int h=;h<=tp;h++)
if((a[h]&g)==&&(a[h]&(g<<))==&&(a[h]&(g>>))==&&j+b[h]<=k)
f[i][j+b[h]][a[h]]+=f[i-][j][g];
for(int i=;i<=end;i++)
ans+=f[n][k][i];
printf("%lld\n",ans);
return ;
}

SGU 223 little kings BSOJ2772 状压DP的更多相关文章

  1. SGU 223 Little Kings(状压DP)

    Description 用字符矩阵来表示一个8x8的棋盘,'.'表示是空格,'P'表示人质,'K'表示骑士.每一步,骑士可以移动到他周围的8个方格中的任意一格.如果你移动到的格子中有人质(即'P'), ...

  2. Kings(状压DP)

    Description 用字符矩阵来表示一个8x8的棋盘,'.'表示是空格,'P'表示人质,'K'表示骑士.每一步,骑士可以移动到他周围的8个方格中的任意一格.如果你移动到的格子中有人质(即'P'), ...

  3. SGU 132. Another Chocolate Maniac 状压dp 难度:1

    132. Another Chocolate Maniac time limit per test: 0.25 sec. memory limit per test: 4096 KB Bob real ...

  4. [SGU223]Little Kings(状压DP)

    随便DP一下 Code #include <cstdio> int sta[150],cnt[150],tp,n,k; long long dp[12][144][150],Ans; in ...

  5. 状压DP SGU 223 Little Kings

    题目传送门 /* 题意:n*n的矩阵,放置k个king,要求king互相不能攻击,即一个king的8个方向都没有另外的king,求方案个数 状态压缩DP:dp[i][num[j]][s] 代表在第i行 ...

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

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

  7. nefu1109 游戏争霸赛(状压dp)

    题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1109 //我们校赛的一个题,状压dp,还在的人用1表示,被淘汰 ...

  8. poj3311 TSP经典状压dp(Traveling Saleman Problem)

    题目链接:http://poj.org/problem?id=3311 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...

  9. [NOIP2016]愤怒的小鸟 D2 T3 状压DP

    [NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...

随机推荐

  1. SceneKit下关于修改SCNNode 的Shader展示自定义图形

    由于某些需求,需要在苹果OS x系统下展示一组点云,准备使用苹果官方的三维显示控件来完成这一功能.场景点云作为离散的点, 如果每个点以SCNnode的形式加入场景中,则回造成过大的内存消耗,笔者电脑下 ...

  2. 纯SVG实现的Loading动画,拿走不谢

    转载自:https://blog.csdn.net/wo_shi_ma_nong/article/details/88833828 话不多说,直接上代码. ( 到这里看效果: http://www.v ...

  3. 用NI的数据采集卡实现简单电子测试之5——压控振荡器的测试

    本文从本人的163博客搬迁至此. 为了展示连续信号采集的方法,以其外部触发采集功能.我用运算放大器实现了一个最简单的低频压控振荡器(VCO),作为USB-6009采集的信号源.在LabVIEW下编写的 ...

  4. 二维码QR Code简介及其解码实现(zxing-cpp)

    二维码QR Code(Quick Response Code)是由Denso公司于1994年9月研制的一种矩阵二维码符号,它具有一维条码及其它二维条码所具有的信息容量大.可靠性高.可表示汉字及图象多种 ...

  5. MongoDB操作-备份和恢复,导入和导出

    mongodb数据备份和恢复主要分为二种:一种是针对库的mongodump和mongorestore,一种是针对库中表的mongoexport和mongoimport 1. 常用命令格式 mongod ...

  6. centos7 安装postgres9.4

    1.安装postgres资源:> yum install https://download.postgresql.org/pub/repos/yum/9.4/redhat/rhel-7-x86_ ...

  7. Bootstrap学习笔记(3)--表格\表单\图片

    Bootstrap表格   表格类:    .table只会在表行之间增加横线;    .table-striped会在表格行之间增减斑马线;    .table-hover会给表设置鼠标悬停状态; ...

  8. MongoDB中设置expire过期自动删除

    关键词: expireAfterSeconds.TTL TTL Time to Live 类似Redis中的expire机制,MongoDB也可以设置过期自动删除的表. MongoDB的过期设置依赖索 ...

  9. 第四节:Windows系统安装时BIOS设置及注意

    BIOS系统 BIOS是英文"Basic Input Output System"的缩略词,直译过来后中文名称就是"基本输入输出系统".在IBM PC兼容系统上 ...

  10. Python对中文的支持

    在Python中,经常会出现中文,出现中文有时候会报错,这时候很多新手在处理中文编码的时候会有点不知所措. Python主要有2.x和3.x版本两个区别,在3.x版本中,已经支持中文直接开发,而不需要 ...