BZOJ1087:[SCOI2005]互不侵犯——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1087
Description
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上
左下右上右下八个方向上附近的各一个格子,共8个格子。
Input
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
Output
方案数。
Sample Input
Sample Output
——————————————————————————————
n很小,暴力太麻烦,考虑状压。
设f[i][j][k]表示前i行放j个国王且第i行排成k情况的时候的情况数有多少。
g[i]表示一行国王排成i情况的时候有几个国王。
转移的时候显然是f[i][j][k]+=f[i-1][j-g[k]][l]
其中保证l合法,并且j最小值为g[k]+g[l]。
于是得到算法构架:
枚举i,枚举k,判断k的合法性,枚举l,判断l的合法性,枚举j,计算。
Q1:g怎么算?
A1:求g[i],我们可以通过将i右移,然后判断i最后一位为0还为1,所以答案为:g[i]=g[i>>1]+(i&1);
Q2:如何判断状态合法?
A2:我们判断相邻行i和j状态之间是否合法,首先判断i和j本身是否合法——通过将本身左移,再和原状态&一下,如果不为0就一定撞上了。
再考虑i和j,同样的思路,将j左/右移和i&(当然反过来也可以),如果不为0就一定撞上了。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
const int N=;
const int INF=;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
int g[N];
ll ans,f[][][N];
int main(){
int n,m;
scanf("%d%d",&n,&m);
if(m>||m>=n*n)puts("");
else{
int t=<<n;f[][][]=;
for(int i=;i<t;i++)g[i]=g[i>>]+(i&);
for(int i=;i<=n;i++){
for(int j=;j<t;j++){
if(g[j]<=m&&!(j&j>>)){
for(int k=;k<t;k++){
if(g[k]<=m&&!(k&k>>)&&!(k&j)&&!(j&k>>)&&!(j&k<<)){
for(int l=g[j]+g[k];l<=m;l++){
f[i][l][j]+=f[i-][l-g[j]][k];
}
}
}
}
}
}
for(int i=;i<t;i++)ans+=f[n][m][i];
printf("%lld\n",ans);
}
return ;
}
BZOJ1087:[SCOI2005]互不侵犯——题解的更多相关文章
- BZOJ1087 SCOI2005 互不侵犯King 【状压DP】
BZOJ1087 SCOI2005 互不侵犯King Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附 ...
- 状压入门--bzoj1087: [SCOI2005]互不侵犯King【状压dp】
Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上 左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行, ...
- [bzoj1087][scoi2005]互不侵犯king
题目大意 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上 左下右上右下八个方向上附近的各一个格子,共8个格子. 思路 首先,搜索可以放弃,因为这是一 ...
- BZOJ1087 [SCOI2005]互不侵犯King 状态压缩动态规划
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1087 题意概括 在n*n的棋盘上面放k个国王,使得他们互相无法攻击,问有多少种摆法. 题解 dp[ ...
- bzoj1087: [SCOI2005]互不侵犯King (codevs2451) 状压dp
唔...今天学了状压就练练手... 点我看题 这题的话,我感觉算是入门题了QAQ... 然而我还是想了好久... 大致自己推出了方程,但是一直挂,调了很久选择了题解 坚持不懈的努力的调代码. 然后发现 ...
- [BZOJ1087][SCOI2005]互不侵犯King解题报告|状压DP
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. 好像若干月前非常Naive地去写过DFS... ...
- bzoj1087 [SCOI2005]互不侵犯
Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包 ...
- [BZOJ1087] [SCOI2005] 互不侵犯King (状压dp)
Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包 ...
- BZOJ1087[SCOI2005]互不侵犯——状压DP
题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. 输入 只有一行,包含两个数N,K ( ...
随机推荐
- php安全性问题
目录 常见攻击类型 1.sql注入: 2.xss攻击 3.csrf攻击: php安全三板斧:过滤输入.验证数据,以及转义输出. 1.数据过滤: 2.验证数据: 3.转义输出: laravel 中如何避 ...
- 这样的SQL居然能执行
select /*! distinct cities.id from cities join countries on cities.id = countries.id limit 10 */;
- ThinkDev.Data更新日志
2013-09-29 10:001.重构Where.And.Or.Having.JoinTable代码,新增条件组合查询QueryGroup2.1.1.2.0 2013-09-04 09:001.修复 ...
- photoshop cc 2018安装破解教程(破解补丁,亲测,绝对可用)
破解步骤说明:下载地址百度网盘,https://pan.baidu.com/s/1cWtpUesl2fms3tFwEC0MiQ 1.右键解压Adobe Photoshop CC 2018 64位这个文 ...
- hdu1181变形课(floyd)
变形课 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Submis ...
- Win10系统XWware虚拟机安装Linux系统(Ubuntu)最新版教程
XWware虚拟机安装Linux系统(Ubuntu)教程 一.下载并安装VMware虚拟机 借助VMware Workstation Pro, 我们可以在同一台Windows或Linux PC上同时运 ...
- C++11 type_traits 之is_same源码分析
请看源码: template<typename _Tp, _Tp __v> struct integral_constant { static const _Tp value = __v; ...
- python学习笔记04 --------------基本运算符
1.算数运算 + 加 - 减 * 乘 / 除 % 取模(先做除法,然后返回余数) ** 乘方(幂运算) // 取整(相除,然后返回商的整数部分) 2.比较运算(返回布尔值) == ...
- Microservices with Spring Boot
找到一套比较不错的Spring Boot/Cloud入门教程,推荐一下. https://dzone.com/users/1041459/ranga_pec.html
- java常见的异常类型
Exception分为两类:非运行是异常和运行时异常. java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常.A:NullPointerExcepti ...