题目: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. mysql常用命令介绍

    mysql适用于在Internet上存取数据,支持多种平台 1.主键:唯一标识表中每行的这个列,没有主键更新或删除表中的特定行很困难. 2.连接mysql可以用Navicat 要读取数据库中的内容先要 ...

  2. Centos 修改源

    1首先备份原来的配置文件: mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 2下载对应版本r ...

  3. 如何在linux搭建airtest+chromeweb测试环境--(用命令行运行.air脚本)

    大前堤: 如果你需要airtest提供的可视化测试报告,那你的操作系统,一定要有图形化界面. 否则运行你的airtest脚本 会遇到这样的问题 Xlib.error.DisplayNameError: ...

  4. Centos初始化硬盘分区、挂载

    刚刚买了一台服务器,刚买的服务器的数据盘都是需要自己来分区的,下面就记录一下操作. 通过命令fdisk-l查看硬盘信息 可以看到有两块硬盘/dev/vda和/dev/vdb,启动vda是系统盘vdb是 ...

  5. centos vm 桥接 --网络配置

    /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 BOOTPROTO=none BROADCAST=192.168.1.255 HWADDR= ...

  6. SVN的一些操作

    一丶 .csproj文件夹必须提交 Revert Changes 撤销

  7. 洛谷——P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm

    P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm 题意翻译 题目描述 每年,在威斯康星州,奶牛们都会穿上衣服,收集农夫约翰在N(1<=N< ...

  8. (C/C++学习)13.C语言字符串处理函数(一)

    说明:字符串处理的函数很多,本文将例举经常遇到的一些函数加以说明. 一.字符串的输入输出 头文件:<stdio.h> 1.利用标准输出函数 printf() 来输出,将格式设置为 s% . ...

  9. Vivaldi解决flash插件问题

    Vivaldi浏览器 Vivaldi是Opera联合创始人.前CEO谭咏文(Jon von Tetzchner)2015年1月27日发布的一款浏览器,具有个性化的笔记功能,带有迷你屏幕截图的书签,以及 ...

  10. Cent os常见操作命令

    1.查看防火墙状态:firewall-cmd –-state 2.关闭防火墙:systemctl stop firewalld.service 3.禁止防火墙开机启动:systemctl disabl ...