题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1556

预处理出两个障碍四个方向之间的距离(转弯次数),就可以状压DP了;

但预处理很麻烦...参考了TJ...:https://blog.csdn.net/senyelicone/article/details/56668048

用 spfa ,记录当前位置带一个朝向,然后转移时判断一下如果朝向不同就+1;

最后再从起点出发同样预处理一下,作为初始状态即可;

注意读入的地图上的 '#' 不仅是机关石,还有墙...所以不能忽略。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int const maxn=,maxm=,inf=0x3f3f3f3f;
int n,m,T,f[<<][maxm][],dis[maxm][][maxm][],d[maxn][maxn][];
int dx[]={,,,-},dy[]={,,-,},xx[maxm],yy[maxm],sx,sy,ans;
bool vis[maxn][maxn],roc[maxn][maxn];
queue<pair<int,int> >q;
bool ck(int x,int y){return x>&&y>&&x<=n&&y<=m;}
void spfa(int nw,int x,int y,int dr)
{
if(roc[x][y]||!ck(x,y))return;
while(q.size())q.pop();
memset(d,0x3f,sizeof d);
q.push(make_pair(x,y)); vis[x][y]=;
for(int k=;k<;k++)d[x][y][k]=;
while(q.size())
{
int nx=q.front().first,ny=q.front().second; q.pop(); vis[nx][ny]=;
for(int i=;i<;i++)
{
int tx=nx+dx[i],ty=ny+dy[i];
if(roc[tx][ty]||!ck(tx,ty))continue;//
for(int j=;j<;j++)
if(d[tx][ty][j]>d[nx][ny][i]+(i!=j))
{
d[tx][ty][j]=d[nx][ny][i]+(i!=j);
if(!vis[tx][ty])vis[tx][ty]=,q.push(make_pair(tx,ty));
}
}
}
for(int i=;i<=T;i++)
for(int j=;j<;j++)//从j撞击xi,yi
{
int tx=xx[i]+dx[j],ty=yy[i]+dy[j],tmp=inf;
for(int k=;k<;k++)tmp=min(tmp,d[tx][ty][k]+(tx+dx[k]!=xx[i]||ty+dy[k]!=yy[i]));//反向
dis[nw][dr][i][j]=tmp;
}
}
int main()
{
scanf("%d%d%d",&n,&m,&T);
char ch[maxn];
for(int i=;i<=n;i++)
{
cin>>ch;
for(int j=;j<m;j++)
if(ch[j]=='#')roc[i][j+]=;
}
for(int i=;i<=T;i++)
{
scanf("%d%d",&xx[i],&yy[i]);
// roc[x][y]=1;//'#'表示墙,不一定是机关石!!!
}
for(int i=;i<=T;i++)
for(int j=;j<;j++)
spfa(i,xx[i]+dx[j],yy[i]+dy[j],j);
scanf("%d%d",&sx,&sy);
spfa(T+,sx,sy,);
memset(f,0x3f,sizeof f); f[][T+][]=;
int mx=(<<T); ans=inf;
for(int s=;s<mx;s++)
for(int i=;i<=T+;i++)
for(int j=;j<=;j++) if(f[s][i][j]!=inf)
for(int k=;k<=T;k++)
for(int l=;l<;l++)
f[s|(<<(k-))][k][l]=min(f[s|(<<(k-))][k][l],f[s][i][j]+dis[i][j][k][l]+);
for(int i=;i<=T;i++)
for(int j=;j<;j++)
ans=min(ans,f[mx-][i][j]);
printf("%d\n",ans);
return ;
}

bzoj 1556 墓地秘密 —— 状压DP的更多相关文章

  1. BZOJ 1087 题解【状压DP】

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

  2. BZOJ 4000: [TJOI2015]棋盘( 状压dp + 矩阵快速幂 )

    状压dp, 然后转移都是一样的, 矩阵乘法+快速幂就行啦. O(logN*2^(3m)) ------------------------------------------------------- ...

  3. BZOJ 4057: [Cerc2012]Kingdoms( 状压dp )

    状压dp.... 我已开始用递归结果就 TLE 了... 不科学啊...我dp基本上都是用递归的..我只好改成递推 , 刷表法 将全部公司用二进制表示 , 压成一个数 . 0 表示破产 , 1 表示没 ...

  4. BZOJ 2073: [POI2004]PRZ( 状压dp )

    早上这道题没调完就去玩NOI网络同步赛了.... 状压dp , dp( s ) 表示 s 状态下所用的最短时间 , 转移就直接暴力枚举子集 . 可以先预处理出每个状态下的重量和时间的信息 . 复杂度是 ...

  5. bzoj 2669 题解(状压dp+搜索+容斥原理)

    这题太难了...看了30篇题解才整明白到底咋回事... 核心思想:状压dp+搜索+容斥 首先我们分析一下,对于一个4*7的棋盘,低点的个数至多只有8个(可以数一数) 这样的话,我们可以进行一个状压,把 ...

  6. BZOJ 2004 公交线路(状压DP+矩阵快速幂)

    注意到每个路线相邻车站的距离不超过K,也就是说我们可以对连续K个车站的状态进行状压. 然后状压DP一下,用矩阵快速幂加速运算即可. #include <stdio.h> #include ...

  7. BZOJ 1226 学校食堂(状压DP)

    状压DP f(i,j,k)表示前i−1个人已经吃了饭,且在i之后的状态为j的人也吃了饭(用二进制表示后面的状态),最后吃的那个人是i之后的第k个 (注意k可以是负数) 然后 如果j&1=1那么 ...

  8. bzoj 2734 集合悬殊 (状压dp)

    大意: 给定$n$, 求集合{1,2,...n}的子集数, 满足若$x$在子集内, 则$2x,3x$不在子集内. 记$f(x)$为$x$除去所有因子2,3后的数, 那么对于所有$f$值相同的数可以划分 ...

  9. BZOJ 2560: 串珠子 (状压DP+枚举子集补集+容斥)

    (Noip提高组及以下),有意者请联系Lydsy2012@163.com,仅限教师及家长用户. 2560: 串珠子 Time Limit: 10 Sec Memory Limit: 128 MB Su ...

随机推荐

  1. html——表单控件

    基本的表单控件还有html5的一些新的表单控件: <!DOCTYPE html> <html> <head> <meta charset="utf- ...

  2. linux下用scp命令在两个服务器之间传输文件,利用php_scp函数进行文件传输

    在linux下利用scp进行文件传输, 从服务器下载文件 scp username@servername:/path/filename /path/filename 上传本地文件到服务器 scp /p ...

  3. 体验SqlServer Express 2014

    想使用SQLServer Express记录一些数据,但使用起来并不令人愉快.SQLServer Express是一个免费的可用数据库,但似乎设置了一些门槛,多少显得并不真心实意.抛开版本(技术)限制 ...

  4. SpringMVC注解配置处理器映射器和处理器适配器

    一.springmvc.xml中配置方式 <!--注解映射器 --> <bean class="org.springframework.web.servlet.mvc.me ...

  5. resize监听div的size变化

    具体实现分两类, ie9-10 默认支持div的resize事件,可以直接通过div.attachEvent('onresize', handler);的方式实现 其它浏览器 通过在div中添加一个内 ...

  6. 哈夫曼树(Huffman Tree)

    Date:2019-06-21 14:42:04 做题时更多的是用到哈夫曼树的构造思想,即按照问题规模从小到大,依次解决问题,可以得到最优解 Description: 在一个果园里,多多已经将所有的果 ...

  7. Linux学习笔记之 Btrfs文件系统简介及使用

    Btrfs 也有一个重要的缺点,当 BTree 中某个节点出现错误时,文件系统将失去该节点之下的所有的文件信息.而 ext2/3 却避免了这种被称为”错误扩散”的问题. Btrfs相关介绍: Btrf ...

  8. Linux:文本处理工具

    闲话少说,列出工具: ========================这些是查看文本用的=========================== 1,cat  用法:cat >f1 直接创建或覆盖 ...

  9. elisp 编程 if 特殊表

    elisp中的 if 特殊表与其他语言中的 if 语句逻辑上并无二致,关键在于如何使用. (if (> 4 3) (message "4 is greater than 3" ...

  10. 火星人 2004年NOIP全国联赛普及组

    题目描述 Description 人类终于登上了火星的土地并且见到了神秘的火星人.人类和火星人都无法理解对方的语言,但是我们的科学家发明了一种用数字交流的方法.这种交流方法是这样的,首先,火星人把一个 ...