题目: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. Ajax——php基础知识(一)

    AMP环境 AMP(Apache.MySQL.PHP)是三个独立的软件,但是对于初学者而言分别安装以及配置需要掌握一定的软件知识,所以就有了很多AMP集成环境帮助我们简化安装 ——WAMP WAMP安 ...

  2. Codeforces_731F_(前缀和)

    F. Video Cards time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  3. Java中内部类详解—匿名内部类

    什么是内部类? 将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类.   成员内部类 定义在类中方法外的类. 定义格式: class 外部类 { class 内部类{ } } ...

  4. 常见的Xshell运行命令

    最近接触到了Xshell这个软件,使用这个软件我们来进行连接Linux系统,进去之后我们可能会两眼一抹黑,小编就带大家来学些常见的shell命令. 首先我们要跟大家从最简单的聊起,我们进入Xshell ...

  5. 20190625 Oracle优化查询(一)

    与其惴惴不安,不如定心应变 前提:我的Oracle服务器是安装在Windows环境中的,没有上到Linux 查看表结构 查询全表 查找空值, 使用“=”是没有结果的,应该使用IS NULL

  6. Python 发送邮件、加密 day5

    一.发送邮件import yagmail username = 'xxxxx@126.com'#发邮件人使用的邮箱 password = '123abc' #免费的邮箱,这里用授权码,一般自己公司的, ...

  7. 最基础的rpm命令

    rpm -ivh package.rpm 安装一个rpm包 rpm -ivh --nodeeps package.rpm 安装一个rpm包而忽略依赖关系警告 rpm -U package.rpm 更新 ...

  8. H5 应用程序缓存(离线缓存)

    离线缓存这个功能的实现有以下步骤: 1,以nginx做web服务器为例,在mime.types文件中添加一行:text/cache-manifest     manifest,作用是为了让服务器识别该 ...

  9. 68.document增删改原理

    主要知识点 document增的原理 document删的原理 document改的原理 一.document增的原理 一个document存入es大致要分以下几个步骤 (1)数据写入buffer, ...

  10. 【tips】ORM - SQLAlchemy操作MySQL数据库

    优先(官方文档SQLAlchemy-version1.2): sqlalchemy | 作者:斯芬克斯 推荐一(长篇幅version1.2.0b3):python约会之ORM-sqlalchemy | ...