【状压DP】bzoj1087 互不侵犯king
一、题目
Description
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上、下、左、右,以及左上、左下、右上、右下八个方向上附近的各一个格子,共8个格子。
Input
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
Output
方案数
Sample Input
3 2
Sample Output
16
原题链接→_→bzoj1087: [SCOI2005]互不侵犯King
二、题目分析
其实我们可以用一张美妙的表来解决这道题(划掉)这道题我们首先考虑暴搜解决,然而似乎状态略多会炸……
搜索不行,我们很容易能想到DP,这里我们引入一个神奇的DP——状态压缩型动态规划。状态压缩是状压DP的核心(废话!),本人在上一篇blog中详细介绍了状态压缩的思想,诸位看官不妨移步一看,可能会对理解状压DP起到一定帮助(链接→_→【宽度优先搜索】神奇的状态压缩 CodeVs1004四子连棋)
对于每一行的状态,我们用1表示国王,0表示不放国王。由于每个位置只有0和1两种状态,我们可以使用位运算判断每行的状态是否合法。例如:10101010就是一种合法状态,而11111111就不合法。每行状态表示的十进制数就是我们压缩后的状态。
我们需要做两个预处理,先枚举每行所有可能的状态,记录下合法状态。然后判断两个状态是否能作为临行放置,并用布尔类型的二维数组存储其关系。
预处理之后,就是常规的DP,状态转移方程如下:
f[i][j][now]=∑f[i-1][j-num[now]][q]
略作说明:f[i][j][k]代表前i行,总共放j个国王,第i行状态为k时的方案数。状态转移方程中的num[now]代表状态为now的行中国王的数目,q表示第i-1行的状态。
三、代码实现
#include<stdio.h>
int n,k;
long long ans;
bool s[],map[][];//判断状态是否合法;判断两个状态是否能作为临行
int num[];//num[i]代表编号为i的状态含有的国王数
long long f[][][];
int sum;
void pre_s()//预处理s数组
{
int i;
for(i=;i<sum;++i)
{
if((i&(i<<))==)
{
s[i]=true;
int t=i,cnt=;
while(t)
{
cnt+=(t&);
t>>=;
}
num[i]=cnt;
f[][cnt][i]=;
}
}
}
void pre_map()//预处理map数组
{
int i,j;
for(i=;i<sum;++i)
{
if(!s[i])continue;
for(j=;j<sum;++j)
{
if(!s[j])continue;
if((!(i&j))&&(!((i<<)&j))&&(!((i>>)&j)))map[i][j]=true;
}
}
}
void dp()
{
int i,j,now;
for(i=;i<=n;++i)
for(j=;j<=k;++j)
for(now=;now<sum;++now)
{
if(!s[now])continue;
if(num[now]>j)continue;
int q;
for(q=;q<sum;q++)
{
if(!s[q])continue;
if(!map[now][q])continue;
if(num[q]+num[now]>j)continue;
f[i][j][now]+=f[i-][j-num[now]][q];
}
}
}
int main()
{
scanf("%d%d",&n,&k);
sum=<<n;
pre_s();
pre_map();
dp();
for(int i=;i<sum;++i)
{
if(!s[i])continue;
ans+=f[n][k][i];
}
printf("%lld",ans);
return ;
}
bzoj1087 互不侵犯king
弱弱地说一句,本蒟蒻码字也不容易,转载请注明出处http://www.cnblogs.com/Maki-Nishikino/p/5992703.html
【状压DP】bzoj1087 互不侵犯king的更多相关文章
- 【状压dp】互不侵犯KING
互不侵犯KING Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3866 Solved: 2264[Submit][Status][Discuss] ...
- 状压DP之互不侵犯
题目描述 这里 在\(N*N\) 的棋盘里面放\(k\)个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. 输入格式 只有 ...
- BZOJ-1087 互不侵犯King 状压DP+DFS预处理
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2337 Solved: 1366 [Submit][ ...
- bzoj1087 互不侵犯King 状压dp+bitset
题目传送门 题目大意:中文题面. 思路:又是格子,n又只有9,所以肯定是状压dp,很明显上面一行的摆放位置会影响下一行,所以先预处理出怎样的二进制摆放法可以放在上下相邻的两行,这里推荐使用bitset ...
- bzoj1087互不侵犯King(状压)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1087 简单的状压dp.但是wa了好几发.注意long long. 注意0和0的连边.而且不能 ...
- 刷题向》关于第一篇状压DP BZOJ1087 (EASY+)
这是本蒟蒻做的第一篇状压DP,有纪念意义. 这道题题目对状压DP十分友善,算是一道模板题. 分析题目,我们发现可以用0和1代表每一个格子的国王情况, 题目所说国王不能相邻放置,那么首先对于每一行是否合 ...
- bzoj1087互不侵犯King——状压DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1087 水题... 然而犯了两个致命小错误,调了好半天...详见注释. 代码如下: #incl ...
- 互不侵犯_状压$dp$
如果有想学习状压\(dp\)的童鞋,请光临博客状压\(dp\)初学 互不侵犯 题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八 ...
- BZOJ1087 SCOI2005 互不侵犯King 【状压DP】
BZOJ1087 SCOI2005 互不侵犯King Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附 ...
随机推荐
- test for cvx library in matlab - windows
Download the zip file of cvx http://cvxr.com/cvx/download/ by downloading cvx-w64.zip Require a lice ...
- 如何理解泛型中的new()约束
一:为什么需要New约束 假设有这样一个需求,它需要在定义一个泛型类时同时实例化T对象.有网友说了:"这还不简单,我立刻给你写一个",刷刷刷,得到以下的例子. public cla ...
- python中常用的模块的总结
1. 模块和包 a.定义: 模块用来从逻辑上组织python代码(变量,函数,类,逻辑:实现一个功能),本质就是.py结尾的python文件.(例如:文件名:test.py,对应的模块名:test) ...
- 【转】Linux下apache/httpd服务启动与停止
apache服务,或者说httpd服务,如何启动,如何开机启动. 转来转去,找不到原文.. 操作系统环境:红帽5,具体如下:# uname -a Linux machine1 2.6.18-164.e ...
- .NET Core Analysis
.NET Core 1.0.1 Module Component .NET Core MongoDB MongoDB.Driver There has a nuget package availabl ...
- python web框架之django环境搭建
一.django环境搭建 https://www.djangoproject.com/download/ 下载适合自己的版本,在右边有压缩包版本的,也可以到git上去拽.我用的python27,下载的 ...
- noi 04:求整数的和与均值
04:求整数的和与均值 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65536kB 描述 读入n(1 <= n <= 10000)个整数,求它们的和与均值. 输入 ...
- OpenCV 轮廓基本特征
http://blog.csdn.net/tiemaxiaosu/article/details/51360499 OpenCV 轮廓基本特征 2016-05-10 10:26 556人阅读 评论( ...
- jsp作为服务端,ajax请求回应
刚学ajax,想以jsp作为服务端,来回应ajax的请求: 代码如下: <!DOCTYPE html> <html> <head lang="en"& ...
- MySQL添加用户、删除用户与授权
MySql中添加用户,新建数据库,用户授权,删除用户,修改密码(注意每行后边都跟个;表示一个命令语句结束): 1.新建用户 1.1 登录MYSQL: @>mysql -u root -p @&g ...