也算难题,难在如何处理有些点可以无限次经过 问题。 这道题,其实很容易想到二分+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. [Swift通天遁地]九、拔剑吧-(6)使用开源类库快速搭建强大的侧边栏项目

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  2. ansible剧本

    yaml简介 YAML是"YAML Ain't a Markup Language"(YAML不是一种置标语言)的递归缩写,早先YAML的意思其实是:"Yet Anoth ...

  3. jQuery使用手册,【新手必备】

    jQuery是一款同prototype一样优秀js开发库类,特别是对css和XPath的支持,使我们写js变得更加方便!如果你不是个js高手又想写出优 秀的js效果,jQuery可以帮你达到目的!   ...

  4. 安装office1406错误!!!急死个人。。。。。

    因为用到Microsoft.Office.Interop.Word,将word转PDF.所以在服务器上需要安装office,但是报错1406,不能将值插入注册表..... 然后百度各种问题,说需要将注 ...

  5. VS2015环境配置: VS2015 未能正确加载“ResourceManagerPackage”包的问题

    启动vs2015专业版时,出现类似于这样的提示框,有好几个,点击是或否,但下次打开还是会出现.笔者也寻找了网上的一些解决办法,例如用vs命令窗口或其他,但都无疾而终,下面提供的这个办法,顺利解决此问题 ...

  6. eclipse 安装svn插件记录

    每个人都有自己喜欢的和习惯的一套开发环境,其中对于喜欢用eclipse的同学来说.subclipse插件可以说是必不可少的插件了. 他的安装有两种方法,一种是在线安装.然而这种安装实在是太慢了,无法忍 ...

  7. 【Java基础】多态

    首先先来个总结: 什么是多态 面向对象的三大特性:封装.继承.多态.从一定角度来看,封装和继承几乎都是为多态而准备的.这是我们最后一个概念,也是最重要的知识点. 多态的定义:指允许不同类的对象对同一消 ...

  8. Android中Webview使用经验总结

    很早前就喜欢在Android中使用Webview组件结合JS来做应用,总结了一些不错的小经验,在这里持续更新,自己备忘,也希望给其他需要的同学一些参考- 1.添加权限 要用Webview,确认你在** ...

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

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

  10. Linux 下phpstudy的安装使用补充说明

    (1)使用方法 在终端中使用sudo 或者 使用管理员账号运行 phpstudy start 开启 (2)命令列表: phpstudy start | stop | restart        开启 ...