题目大意

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

题解

这跟“炮兵阵地”很是相似。定义一行的状态\(S\)为是否安放国王的01集合。先预处理出一行中两两国王无法攻击的所有状态(以后简称合理状态),以及这些状态中1的个数\(g(S)\)。定义\(f(r,S,k)\)为当第\(r\)行的状态为\(S\)时,1至\(r\)行中存在\(k\)个国王的安排有多少种。则递归式为:

\[f(r,S,k)=\sum_{S'\And(S|(S<<1)|(S>>1))=0}f(r-1,S',k-g(S))
\]

实际上,S用可行状态的编号表示即可。

注意

  • f数组中用来存放S的大小应当是1<<MAX_N,而不是MAX_N,因为合理状态的数量可能比N多,最大编号也就比N多了。
  • 注意递归式中与\(S'\)与操作的还有\(S\)。
  • 最后统计结果时,枚举S的终止条件为达到最大合理状态的编号,而不是N。注意下定义。

关于暴力

一个一个枚举国王可能在的位置。因为重合子问题\(f(r,S,k)\)被计算了多次,故不是正解。但是要做到正确,注意:

  • 用来恢复现场的数据应当保存在系统栈内,而不是放在堆中供多次递归函数共用。这就错了。
  • 仔细检查,防止手误。

AC代码:

#include <cstdio>
#include <cstring>
#include <bitset>
#include <iostream>
using namespace std; #define ll long long const int MAX_N = 10, MAX_K = 100;
ll F[MAX_N][1<<MAX_N][MAX_K];
int States[1<<MAX_N], State1Cnt[1<<MAX_N];
int N, StCnt, K; void GetProperState(int n)
{
StCnt = 0;
for (int i = 0; i <= ~(~1 << n - 1); i++)
{
if (!(i << 1 & i))
{
States[StCnt] = i;
int temp = i;
while (temp)
{
if (temp & 1)
State1Cnt[StCnt]++;
temp >>= 1;
}
StCnt++;
}
}
} void PrintBinary(ll x)
{
cout << bitset<5>(x);
} ll DP()
{
ll ans = 0;
for (int i = 0; i <= StCnt; i++)
F[0][i][State1Cnt[i]] = 1;
for (int level = 1; level < N; level++)
for (int i = 0; i < StCnt; i++)
for (int j = 0; j < StCnt; j++)
if (!(States[i]&States[j])&&!((States[i] << 1) & States[j]) && !((States[i] >> 1) & States[j]))
for (int k = State1Cnt[i]; k <= K; k++)
F[level][i][k] += F[level - 1][j][k - State1Cnt[i]];
for (int i = 0; i < StCnt; i++)
ans += F[N - 1][i][K];
return ans;
} int main()
{
scanf("%d%d", &N, &K);
GetProperState(N);
printf("%lld\n", DP());
return 0;
}

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

  1. BZOJ1087[SCOI2005]互不侵犯——状压DP

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

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

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

  3. SCOI2005 互不侵犯 [状压dp]

    题目传送门 题目大意:有n*n个格子,你需要放置k个国王使得它们无法互相攻击,每个国王的攻击范围为上下左走,左上右上左下右下,共8个格子,求最多的方法数 看到题目,是不是一下子就想到了玉米田那道题,如 ...

  4. [SCOI2005]互不侵犯 (状压$dp$)

    题目链接 Solution 状压 \(dp\) . \(f[i][j][k]\) 代表前 \(i\) 列中 , 已经安置 \(j\) 位国王,且最后一位状态为 \(k\) . 然后就可以很轻松的转移了 ...

  5. NOI P1896 互不侵犯 状压DP

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

  6. _bzoj1087 [SCOI2005]互不侵犯King【dp】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1087 令f(i, j, k)表示前i列,二进制状态为j,已经用了k个国王的方案数,则 f(i ...

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

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

  8. 状压DP概念 及例题(洛谷 P1896 互不侵犯)

    状压DP 就是状态压缩DP.所谓状态压缩,就是将一些复杂的状态压缩起来,一般来说是压缩为一个二进制数,用01来表示某一元素的状态. 比如一排灯泡(5个) 我们可以用一串二进制01串来表示他们的状态 1 ...

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

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

随机推荐

  1. NoSQL概念

    NoSQL是非关系型数据库,即not only sql,key/value键值对存储. 现有Nosql DB产品:Redis/MongoDB/Memcached等等. SQL Sever是关系型数据库 ...

  2. [转载]MySql事物处理

    事务处理在各种管理系统中都有着广泛的应用,比如人员管理系统,很多同步数据库操作大都需要用到事务处理.比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如 ...

  3. 菜鸟使用 centOS 安装 redis 并放入service 启动 记录

    1.下载redis: wget http://download.redis.io/releases/redis-2.8.17.tar.gz 若wget 不可用,请先安装wget yum install ...

  4. SAP computer之architecture

    Simple-As-Possible computer introduces all the cruicial ideas behind computer operation without bury ...

  5. 《Linux程序设计》笔记(一)入门

    1. 头文件 使用-I标志来包含头文件. gcc -I/usr/openwin/include fred.c 2. 库文件 通过给出 完整的库文件路径名 或 用-l标志 来告诉编译器要搜索的库文件. ...

  6. 在MFC中使用Cstring

    此文介绍了关于MFC使用CString的资料,可一参考一下. 转自于VC知识库:http://www.vckbase.com/index.php/wv/829 通过阅读本文你可以学习如何有效地使用 C ...

  7. Can't find variable: SockJS vue项目

    用的vue-cli(webpack-simple模板),在开发环境运行(npm run dev),一直都没有问题,突然在ios的safari中调试,出现报错:Can't find variable: ...

  8. java模拟Cookies登陆

    在使用java访问URL时,如果该URL需要身份验证,那么就不能够直接访问,因为没有登陆.那么,如何解决这个问题呢? 方法是使用java模拟登陆,登陆后记录下cookie信息,在下次发起请求时时将co ...

  9. Tomcat Eclipse Debug出现异常

    1.可能是java类没有及时更新成class文件2.本地程序没有同步到Tommcat服务器里面3.Servlet类里面加了版本号private static final long serialVers ...

  10. 01 DOS常用命令

    有时候没有可视化窗口,命令行对文件进行操作更方便快捷 cmd 命令弹出 dir 查看当前所在目录下的文件 ctrl+c 退出 \a 显示隐藏文件 cd /改变到根目录 dir /a 显示隐藏文件 di ...