题目: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. Matrix computations in C

    meschach配置使用 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !im ...

  2. logstash windows下添加服务启动管理

    nssm下载链接:http://nssm.cc/release/nssm-2.24.zip

  3. jenkins环境搭建(Windows)

    1.下载并解压Tomcat Tomcat官方网站:http://tomcat.apache.org/ 下载并解压,解压后的目录结构如下: 2.下载并安装适合自己电脑系统的 jenkins Jenkin ...

  4. IDEA生成增强for循环

    itar 生成array for代码块 for (int i = 0; i < array.length; i++) { = array[i]; } itco 生成Collection迭代 fo ...

  5. PAT_A1003#Emergency

    Source: PAT A1003 Emergency (25 分) Description: As an emergency rescue team leader of a city, you ar ...

  6. Django - 路由对应关系

    1.对url路由关系命名,以后可以根据此名称,生成自己想要的url urls.py中: url('^fdsaafdf(\d+)/',views.index,name='indexx') url('^f ...

  7. jquery spa

    1.hashchange监听 2.根据url加载不同页面 $.ajax({ url:"/xx/xx.html" type:"get", dataType:&qu ...

  8. rpm包下载地址

    https://dl.fedoraproject.org/pub/epel/6/x86_64/

  9. LINUX 查看硬件配置命令

      系统 # uname -a # 查看内核/操作系统/CPU信息 # head -n 1 /etc/issue # 查看操作系统版本 # cat /proc/cpuinfo # 查看CPU信息 # ...

  10. noip模拟赛 正方形

    题目描述在一个10000*10000的二维平面上,有n颗糖果.LYK喜欢吃糖果!并且它给自己立了规定,一定要吃其中的至少C颗糖果!事与愿违,LYK只被允许圈出一个正方形,它只能吃在正方形里面的糖果.并 ...