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[n][i][m];
printf("%lld\n",ans);
}

可以滚动数组滚掉第\(1\)维,切在枚举\(l\)的时候,第三维可能会超内存,因此要开大一点.当然也可以判断一下\(l+now \leq m\)

状压DP【p1896】[SCOI2005]互不侵犯的更多相关文章

  1. 状压入门--bzoj1087: [SCOI2005]互不侵犯King【状压dp】

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

  2. 【状压DP】bzoj1087 互不侵犯king

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

  3. 洛谷 P1896 [SCOI2005]互不侵犯

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

  4. 洛谷——P1896 [SCOI2005]互不侵犯

    P1896 [SCOI2005]互不侵犯 状压DP入门题 状压DP一般需要与处理状态是否合法,节省时间 设定状态dp[i][j][k]表示第i行第j个状态选择国王数为k的方案数 $dp[i][j][n ...

  5. 洛谷P1896 [SCOI2005]互不侵犯King

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

  6. 【题解】洛谷P1896 [SCOI2005] 互不侵犯(状压DP)

    洛谷P1896:https://www.luogu.org/problemnew/show/P1896 前言 这是一道状压DP的经典题 原来已经做过了 但是快要NOIP 复习一波 关于一些位运算的知识 ...

  7. P1896 [SCOI2005]互不侵犯 状压dp

    正解:状压dp 解题报告: 看到是四川省选的时候我心里慌得一批TT然后看到难度之后放下心来觉得大概没有那么难 事实证明我还是too young too simple了QAQ难到爆炸TT我本来还想刚一道 ...

  8. P1896 [SCOI2005]互不侵犯King

    题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. 输入输出格式 输入格式: 只有一行,包 ...

  9. P1896 [SCOI2005]互不侵犯

    题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. 注:数据有加强(2018/4/25) ...

  10. P1896 [SCOI2005] 互不侵犯 方法记录

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

随机推荐

  1. Python 实现随机打乱字符串

    from random import shuffle def shuffle_str(s): # 将字符串转换成列表 str_list = list(s) # 调用random模块的shuffle函数 ...

  2. [转]unity之LOD

    LOD技术有点类似于Mipmap技术,不同的是,LOD是对模型建立了一个模型金字塔,根据摄像机距离对象的远近,选择使用不同精度的模型. 它的好处是可以在适当的时候大量减少需要绘制的顶点数目. 它的缺点 ...

  3. Qt 中C++ static_cast 和 reinterpret_cast的区别

    1.C++中的static_cast执行非多态的转换,用于代替C中通常的转换操作.因此,被做为隐式类型转换使用.比如: int i; float f = 166.7f; i = static_cast ...

  4. springboot04 Ajax json Jquery

    一.Ajax 1.同步&异步请求 在所有的请求响应交互世界里,我们有通常会划分出来两种形态的请求, 一种是同步请求.另一种是异步请求 .比如注册.登录.添加数据等等这些请求执行的就是同步请求, ...

  5. django QuerySet 的常用API

    为了加深对queryset对象api的了解,我们建立了以下示例模型: from django.db import models class Author(models.Model): "&q ...

  6. 使用Bootstrap框架的HTML5页面模板

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. (转)彻底隐藏Nginx版本号的安全性与方法

    Nginx默认是显示版本号的,如: [root@bkjz ~]# curl -I www.nginx.orgHTTP/1.1 200 OKServer: nginx/0.8.44Date: Tue, ...

  8. 【noip2016d2t3】状压DP+巧妙优化

    题意可以简单这样考虑 给出n^2个集合(每个集合的元素不超过n),包含某个元素的集合至少有n个,选出最少的集合,使这些集合的并包含n个元素 n最大只有18 可以考虑状压n个元素,然后枚举n^2个集合 ...

  9. HDU - 3072 Intelligence System

    题意: 给出一个N个节点的有向图.图中任意两点进行通信的代价为路径上的边权和.如果两个点能互相到达那么代价为0.问从点0开始向其余所有点通信的最小代价和.保证能向所有点通信. 题解: 求出所有的强连通 ...

  10. 叶落归根(hometown)

    叶落归根(hometown) 题目描述 叶落归根——树叶从树根生发出来,凋落后最终还是回到树根.比喻事物总有一定的归宿.接下来是题目. 给定一个n个点的有向图G(点的编号为1~n),一开始落叶(仅作为 ...