也算难题,难在如何处理有些点可以无限次经过 问题。 这道题,其实很容易想到二分+TSP的状态压缩,但在处理上述问题时,确实没想到。题解是处理每一个Y或G或F点到其他YGF点的距离,BFS,这样就出现一个点只访问一次,而且即便在原图上重复经过某点,在重建的图也不会体现出来了。绝!

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; char map[16][16];
bool vis[16][16];
int cnt,dp[1<<16][16];
struct Node{
int x,y;
}node[16];
int dis[16][16][16][16];
const int inf=(1<<30);
int n,m,fp,head,tail;
int dir[4][2]={
{0,1},
{0,-1},
{1,0},
{-1,0}
};
Node que[400];
int endfor; bool ok(int x,int y){
if(x>=0&&x<n&&y>=0&&y<m&&map[x][y]!='D'&&!vis[x][y]) return true;
return false;
} void bfs(Node start){
Node tmp;
vis[start.x][start.y]=true;
que[tail++]=start;
int step=0;
while(head<tail){
int sz=tail-head;
step++;
while(sz--){
Node ss=que[head++];
for(int i=0;i<4;i++){
tmp.x=ss.x+dir[i][0];
tmp.y=ss.y+dir[i][1];
if(ok(tmp.x,tmp.y)){
if(map[tmp.x][tmp.y]=='G'||map[tmp.x][tmp.y]=='Y'){
dis[start.x][start.y][tmp.x][tmp.y]=step;
// cout<<start.x<<" "<<start.y<<" "<<tmp.x<<" "<<tmp.y<<" "<<step<<endl;
}
que[tail++]=tmp;
vis[tmp.x][tmp.y]=true;
}
}
}
}
} bool check(int bat){
memset(dp,-1,sizeof(dp));
int alt=1<<cnt;
dp[1<<fp][fp]=bat;
for(int i=0;i<alt;i++){
for(int j=0;j<cnt;j++){
if(dp[i][j]==-1) continue;
if((i&endfor)==endfor){
if(dp[i][j]!=-1) return true;
}
for(int k=0;k<cnt;k++){
if(dis[node[j].x][node[j].y][node[k].x][node[k].y]==-1) continue;
if(i&(1<<k)) continue;
if(dp[i][j]-dis[node[j].x][node[j].y][node[k].x][node[k].y]<0) continue;
int tmp=dp[i][j]-dis[node[j].x][node[j].y][node[k].x][node[k].y];
if(map[node[k].x][node[k].y]=='G') tmp=bat;
if(tmp>dp[i|(1<<k)][k]) dp[i|(1<<k)][k]=tmp;
}
}
}
return false;
} void slove(){
int l=0,r=1000;
int res=r;
while(l<=r){
int m=(l+r)/2;
if(check(m)){
res=m;
r=m-1;
}
else l=m+1;
}
if(res==1000) printf("-1\n");
else printf("%d\n",res);
} int main(){
while(scanf("%d%d",&n,&m),n||m){
cnt=0;
endfor=0;
for(int i=0;i<n;i++){
scanf("%s",map[i]);
// cout<<map[i]<<endl;
for(int j=0;j<m;j++){
if(map[i][j]=='F'){
fp=cnt;
node[cnt].x=i,node[cnt].y=j;
cnt++;
}
else if(map[i][j]=='G'){
node[cnt].x=i,node[cnt].y=j;
cnt++;
}
else if(map[i][j]=='Y'){
node[cnt].x=i,node[cnt].y=j;
endfor+=(1<<cnt);
cnt++;
}
}
}
memset(dis,-1,sizeof(dis));
for(int i=0;i<cnt;i++){
head=tail=0;
memset(vis,false,sizeof(vis));
bfs(node[i]);
}
slove();
}
return 0;
}

  

HDU 3681的更多相关文章

  1. HDU 3681 Prison Break(状态压缩dp + BFS)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3681 前些天花时间看到的题目,但写出不来,弱弱的放弃了.没想到现在学弟居然写出这种代码来,大吃一惊附加 ...

  2. hdu 3681 Prison Break

    http://acm.hdu.edu.cn/showproblem.php?pid=3681 题意:一个n*m的矩阵,'F'是起点.机器人从F出发,走到G可以充电,走到Y关掉开关,D不能走进,要求把所 ...

  3. hdu 3681(bfs+二分+状压dp判断)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3681 思路:机器人从出发点出发要求走过所有的Y,因为点很少,所以就能想到经典的TSP问题.首先bfs预 ...

  4. HDU 3681 Prison Break(BFS+二分+状态压缩DP)

    Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But one da ...

  5. hdu 3681 Prison Break (TSP问题)

    Prison Break Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot ...

  6. hdu 3681 Prison Break(状态压缩+bfs)

    Problem Description Rompire . Now it’s time to escape, but Micheal# needs an optimal plan and he con ...

  7. HDU 3681 BFS&amp;像缩进DP&amp;二分法

    N*M矩阵.从F出发点.走完全部Y点.每个人格开支1电源点,去G点,电池充满,D无法访问.最小的开始问什么时候满负荷可以去完全部Y.Y和G总共高达15一 第一BFS所有的F.Y.G之间的最短距离. 然 ...

  8. HDU 3681 Prison Break (二分 + bfs + TSP)

    题意:给定上一个 n * m的矩阵,你的出发点是 F,你初始有一个电量,每走一步就会少1,如果遇到G,那么就会加满,每个G只能第一次使用,问你把所有的Y都经过,初始电量最少是多少. 析:首先先预处理每 ...

  9. hdu 3681 压缩dp+搜索

    题意:一个机器人想越狱,他只能带一定电量的电池,'S'表示道路可行,'G'表示充电器, 只可充电一次,但是可以经过很多次.'F'表示起点,'Y'表示要破坏的机关,也是只能破坏一次,但是可以经过无数次. ...

  10. HDU 3681 Prison Break 越狱(状压DP,变形)

    题意: 给一个n*m的矩阵,每个格子中有一个大写字母,一个机器人从‘F’出发,拾取所有的开关‘Y’时便能够越狱,但是每走一格需要花费1点能量,部分格子为充电站‘G’,每个电站只能充1次电.而且部分格子 ...

随机推荐

  1. ubuntu16.04更改源

    最近用apt-get安装软件总是提示列表无法全部更新,导致一些软件安装不上,下面我们通过讲/etc/apt/sources.list里为阿里源,实现访问. 第一步: 备份/etc/apt/source ...

  2. C#中Random

    说明:C#中的随机数是一个伪随机数,随机数字从一组有限的数字选择以相同的概率,所选的数字不是完全随机的,因为使用数学算法来选择它们.在大多数Windows系统中,Random的15毫秒内创建的对象很可 ...

  3. 类型判断----小白讲解typeof,instanceof,Object.prototype.toString.call()

    1.typeof只能判断基本类型数据, 例子: typeof 1 // "number" typeof '1' // "string" typeof true ...

  4. python自动化测试学习笔记-4常用模块

    常用模块 1.os 2.sys 3.random 4.string 5.time 6.hashlib 一.os模块 os模块主要用来操作文件.目录,与操作系统无关.要使用os模块首先要导入OS模块,用 ...

  5. 实例化flask的参数及对app的配置

    Flask 是一个非常灵活且短小精干的web框架 , 那么灵活性从什么地方体现呢? 有一个神奇的东西叫 Flask配置 , 这个东西怎么用呢? 它能给我们带来怎么样的方便呢? 首先展示一下: from ...

  6. Quartz在服务异常中断或者重启后,不执行之前漏掉的任务,重新运行下一次任务

    Quartz默认重启后会执行之前的任务,所以如果不想执行之前漏掉的任务,需要设置一下两个地方: CRON triggers CronTrigger trigger = TriggerBuilder.n ...

  7. Laravel 5.4.36 session 发现

    由于Laravel session机制完全脱离了PHP自带的session机制  因此对于php.ini 配置session对Laravel  是不会产生影响 代码路径:   vendor/larav ...

  8. photoshop制作古风画

    效果图: 素材结构: 前期准备: 素材准备,我的素材包括:印章.花束.二次元妹纸,背景图片. 软件准备,用的软件是 photoshop CS6. 把二次元妹纸拖入photoshop,把她抠出来,Ctr ...

  9. html5——web字体

    基本介绍 1.自定义网页特殊字体,无需考虑用户电脑上是否安装了此特殊字体,从此把特殊字体处理成图片的时代便成为了过去. 2.支持程度比较好,甚至IE低版本浏览器也能支持. 3.web字体的大小鉴定是字 ...

  10. spring+spring MVC+mybatis 框架搭建

    1.新建一个javaWeb工程Test,创建时记得勾选web.xml文件. 2.导入需要的jar包,Mybatis所有的jar,spring所有的jar,mysql驱动包. 这里mybatis和spr ...