BZOJ1087状压DP 解题报告
1087: [SCOI2005]互不侵犯King
Description
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上
左下右上右下八个方向上附近的各一个格子,共8个格子。
Input
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
Output
方案数。
Sample Input
Sample Output
状态压缩DP第一道题。作为第一道题。其实对于我这种动态规划都是自学的人来说。难度很大。但是。研读各大神犇的标程和解析后。开始慢慢的明白了一些,所以这里给一句忠告。没什么啃不下来的东西,如果啃不下来,那就多啃一会。
说起动态规划。总是让我想起一系列问题。什么是状态,怎么转移,怎样决策。而这道题,好像没怎么用道决策。但是。什么是状态呢?怎么样在这道题实现转移。这是值得思考的。不思考是没有进步的。
而这道题让我们一眼就可以想到DFS暴力枚举,以每个节点开始。枚举接下来每个点的位置。用二维数组来模拟位置的摆放。DFS递归的其实可以打表出来。而这个方法潜在的状态是上一个点的“位置”。每次枚举的是“位置”。
这道题思考起来。关键:压缩。当发现是这种二维,而且DFS要炸的题。首先考虑压缩。降维?康托-压缩状态?。这里想到的是,以一层为一个状态元素。而我们知道这个状态有很多。因为最多就只有9*9,就9层。每一层有9个格子。那么我们可以提前预处理出来一层里面每一种正确的摆放方式,如果这种方式正确则打上标记。这里国王就只有摆或者不摆,很显然我们可以想到有可以用二进制来表示一层的状态,这样,一层就被我们压缩成一个数。一种可行性方案也被我们压成了一个数。
接下来的就是对于每一层进行递推。我们都已经把每一种情况枚举出来。考虑每两层之间的关系,DP转移就成了枚举两层的可能组合性,之后就是方案数的转移。
这里给出 F[i][q][j] (一种状态) 其中这里的i代表层数,这里的j代表这一层如果是j这个状态。q代表着一层及其以上的所有放的国王数量。这里的j就指的是放的方式,举个栗子 j==85 那么那一层的方式就是 1010101(2)就是这样der。
枚举每两层方式。F [i] [q+cnt_1[a]] [a] += F[i-1] [q] [j];这个意思就是,如果上一层的摆放方式为J,这一层的摆放方式为a 那么这一层放q+(a方式的摆放国王的数量)的状态 是由 上一层摆放方式为j 摆放数量为q 的状态转移过来。(其中状态里存的是方案数)
#include<cstdio>
#include<algorithm>
using namespace std;
int cnt[512],map_1[512][512],cnt_1[512];
long long int f[10][512][512];
int n,k,all;
int first()
{
int s;
for(int i=0;i<=all;i++)
if(((i>>1)&i)==0)//注释1
{
cnt[i]=1;
s=0;
for(int j=i;j;j>>=1)s+=(j&1);
cnt_1[i]=s;
}
for(int i=0;i<=all;i++)if(cnt[i])
for(int j=0;j<=all;j++)if(cnt[j])
if( ((i&j)==0) && (((i>>1)&j)==0) && (((j>>1)&i)==0))
map_1[i][j]=1; //注释2
return 0;
}
int main()
{
scanf("%d%d",&n,&k);
all=(1<<n)-1;
first( );
for(int i=0;i<=all;++i)if(cnt[i])f[1][cnt_1[i]][i]=1;
for(int i=2;i<=n;++i)
for(int a=0;a<=all;++a)if(cnt[a])
for(int j=0;j<=all;++j)if(cnt[j])
if(map_1[j][a])
for(int q=cnt_1[j];q+cnt_1[a]<=k;++q) //注释3
f[i][q+cnt_1[a]][a]+=f[i-1][q][j];
long long int ans=0;
for(int i=0;i<=all;++i)ans+=f[n][k][i];
printf("%lld",ans);
return 0;
}
注释:
1,这里作用是判断是否这种状态是不是正确。
2,判断两种状态能不能出线在一起(上下层)
3,这里枚举q,因为每一层结合上一层还有这一层摆放的方式有很多,所以要考虑全面。
最重要的一条
不开long long见祖宗
不开long long见祖宗
不开long long见祖宗
不开long long见祖宗
不开long long见祖宗
不开long long见祖宗
BZOJ1087状压DP 解题报告的更多相关文章
- poj - 1185 炮兵阵地 状压DP 解题报告
炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 21553 Accepted: 8363 Description ...
- P1896 [SCOI2005]互不侵犯 状压dp
正解:状压dp 解题报告: 看到是四川省选的时候我心里慌得一批TT然后看到难度之后放下心来觉得大概没有那么难 事实证明我还是too young too simple了QAQ难到爆炸TT我本来还想刚一道 ...
- 洛谷$P3959\ [NOIp2017]$ 宝藏 状压$dp$
正解:状压$dp$ 解题报告: 传送门$QwQ$ $8102$年的时候就想搞这题了,,,$9102$了$gql$终于开始做这题了$kk$ 发现有意义的状态只有当前选的点集和深度,所以设$f_{i,j} ...
- 洛谷$P$3160 局部极小值 $[CQOI2012]$ 状压$dp$
正解:状压$dp$ 解题报告: 传送门! 什么神仙题昂,,,反正我是没有想到$dp$的呢$kk$,,,还是太菜了$QAQ$ 首先看数据范围,一个4×7的方格,不难想到最多有8个局部极小值,过于显然懒得 ...
- [BZOJ1087][SCOI2005]互不侵犯King解题报告|状压DP
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. 好像若干月前非常Naive地去写过DFS... ...
- 【状压DP】bzoj1087 互不侵犯king
一.题目 Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上.下.左.右,以及左上.左下.右上.右下八个方向上附近的各一个格子,共8个格子. I ...
- 【BZOJ1087】 [SCOI2005]互不侵犯King 状压DP
经典状压DP. f[i][j][k]=sum(f[i-1][j-cnt[k]][k]); cnt[i]放置情况为i时的国王数量 前I行放置情况为k时国王数量为J #include <iostre ...
- BZOJ-1087 互不侵犯King 状压DP+DFS预处理
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2337 Solved: 1366 [Submit][ ...
- [BZOJ1087] [SCOI2005] 互不侵犯King (状压dp)
Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包 ...
随机推荐
- Android 源码获取-----在Windows环境下通过Git得到Android源代码
在学习Android的过程中,深入其源代码研究对我们来说是非常重要的,这里将介绍如何通过在Windows环境下使用Git来得到我们的Android源代码. 1.首先确保你电脑上安装了Git,这个通过 ...
- Oracle Essbase入门系列(一)
1. 开篇序 本文是几年前做Hyperion Planning项目时写的,后来陆陆续续有些补充.本来打算将整个EPM写一系列的教程,但HFM写到1/3就没动力了.不过至少Essbase这部分是完整的. ...
- CKEditor4.1和CKFinder2.3.1 for Mvc4最新 破解版,结合 打造"帅"的编辑器 For .Net
CKEditor4.1+CKFinder2.3.1 FOR MVC4 最新破解版:(2013-3-23) baidu share: http://pan.baidu.com/share/link?sh ...
- [Unit Testing] AngularJS Unit Testing - Karma
Install Karam: npm install -g karma npm install -g karma-cli Init Karam: karma init First test: 1. A ...
- cmd实用命令
1.netstat 查看电脑端口状况 实际应用举例:查看某软件坚监听的电脑端口. 在任务管理器中选择列...,打开PID的显示.在这里查看某个应用程序的线程ID是多少.例如QQ:4904. 运行,cm ...
- Office 2013 Excel 转换 Word
最新文章:Virson's Blog 参考文章:百度百科 1.使用Excel打开需要转换的Excel文档: 2.采用另存为*.htm的方式将该Excel文档另存为网页,如下图: 3.找到保存的htm网 ...
- TabHost的用法(转)
本文结合源代码和实例来说明TabHost的用法. 使用TabHost 可以在一个屏幕间进行不同版面的切换,例如android自带的拨号应用,截图: 查看tabhost的源代码,主要实例变量有: pr ...
- 一段时间没上来了,看到有很多网友对OWA感兴趣,因为所在公司发展方向的原因,没有太多时间继续深入研究OWA,敬请见谅
一段时间没上来了,看到有很多网友对OWA感兴趣,因为所在公司发展方向的原因,没有太多时间继续深入研究OWA,敬请见谅
- 牛顿方法(Newton-Raphson Method)
本博客已经迁往http://www.kemaswill.com/, 博客园这边也会继续更新, 欢迎关注~ 牛顿方法是一种求解等式的非常有效的数值分析方法. 1. 牛顿方法 假设\(x_0\)是等式的 ...
- C头文件和源文件的连
(http://blog.163.com/yui_program/blog/static/18415541520115177852896/) 一.源文件如何根据#include来关联头文件 1,系统自 ...