bzoj 1556 墓地秘密 —— 状压DP
题目: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的更多相关文章
- BZOJ 1087 题解【状压DP】
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3112 Solved: 1816[Submit][ ...
- BZOJ 4000: [TJOI2015]棋盘( 状压dp + 矩阵快速幂 )
状压dp, 然后转移都是一样的, 矩阵乘法+快速幂就行啦. O(logN*2^(3m)) ------------------------------------------------------- ...
- BZOJ 4057: [Cerc2012]Kingdoms( 状压dp )
状压dp.... 我已开始用递归结果就 TLE 了... 不科学啊...我dp基本上都是用递归的..我只好改成递推 , 刷表法 将全部公司用二进制表示 , 压成一个数 . 0 表示破产 , 1 表示没 ...
- BZOJ 2073: [POI2004]PRZ( 状压dp )
早上这道题没调完就去玩NOI网络同步赛了.... 状压dp , dp( s ) 表示 s 状态下所用的最短时间 , 转移就直接暴力枚举子集 . 可以先预处理出每个状态下的重量和时间的信息 . 复杂度是 ...
- bzoj 2669 题解(状压dp+搜索+容斥原理)
这题太难了...看了30篇题解才整明白到底咋回事... 核心思想:状压dp+搜索+容斥 首先我们分析一下,对于一个4*7的棋盘,低点的个数至多只有8个(可以数一数) 这样的话,我们可以进行一个状压,把 ...
- BZOJ 2004 公交线路(状压DP+矩阵快速幂)
注意到每个路线相邻车站的距离不超过K,也就是说我们可以对连续K个车站的状态进行状压. 然后状压DP一下,用矩阵快速幂加速运算即可. #include <stdio.h> #include ...
- BZOJ 1226 学校食堂(状压DP)
状压DP f(i,j,k)表示前i−1个人已经吃了饭,且在i之后的状态为j的人也吃了饭(用二进制表示后面的状态),最后吃的那个人是i之后的第k个 (注意k可以是负数) 然后 如果j&1=1那么 ...
- bzoj 2734 集合悬殊 (状压dp)
大意: 给定$n$, 求集合{1,2,...n}的子集数, 满足若$x$在子集内, 则$2x,3x$不在子集内. 记$f(x)$为$x$除去所有因子2,3后的数, 那么对于所有$f$值相同的数可以划分 ...
- BZOJ 2560: 串珠子 (状压DP+枚举子集补集+容斥)
(Noip提高组及以下),有意者请联系Lydsy2012@163.com,仅限教师及家长用户. 2560: 串珠子 Time Limit: 10 Sec Memory Limit: 128 MB Su ...
随机推荐
- JS高级——作用域链
基本概念 1.只要是函数就可以创造作用域 2.函数中又可以再创建函数 3.函数内部的作用域可以访问函数外部的作用域 4.如果有多个函数嵌套,那么就会构成一个链式访问结构,这就是作用域链 <scr ...
- ASP.NET 缓存(Cache)
ASP.NET提供了在一个ASP.NET应用程序基本上缓存信息的编程功能.该功能和Application对象相似,但它具有在ASP.NET应用程序的生命周期内动态维护缓存信息的能力.在应用程序中缓存数 ...
- python编辑csv
import csv import time def timestamp_to_timestr(timeStamp): timeArray = time.localtime(int(timeStamp ...
- CNN结构:Windows使用FasterRCNN-C++版本
参考文章:Windows下VS2013 C++编译测试faster-rcnn. 本文与作者的所写方法有些许不同,欲速则不达,没有按照作者的推荐方法,绕了个弯弯. Windows版本纯C++版本的Fas ...
- 取textaera里的值
jQuery的.val()方法是专门用来获取表单元素值的,而textarea也属于表单元素所以可以直接用.val()方法获取. 不过要注意,由于textarea是个双标记因此.text()或.html ...
- 模态框(layer)
推荐一个好看的模态框(layer) 地址:http://layer.layui.com/ 相应列子及配置 全部来自于官网,可直接访问官网学习了解. //信息框-例1 layer.alert('见 ...
- SGU100
Read integers A and B from input file and write their sum in output file. Input Input file contains ...
- golang实现高阶函数之filter
package main import "fmt" type student struct{ name string grade int8 } func filter(stu [] ...
- DFA最小化实例
原始DFA如下图所示 最小化的定义:1.没有多余的状态(死状态):2.没有两个状态是相互等价的: 两个状态等价的含义:1.兼容性(一致性)——同是终态或同是非终态:2.传播性(蔓延性)——从s出发读入 ...
- 洛谷 3203 HNOI2010 BOUNCE 弹飞绵羊
[题解] 这道题可以用Link-Cut Tree写.. 首先建立一个虚拟节点N+1,$i$与$N+1$连边表示$i$被弹飞了 对于修改操作,先$cut(i,min(n+1,i+k[i]))$,然后再$ ...