http://acm.hdu.edu.cn/showproblem.php?pid=3681

题意:一个n*m的矩阵,'F'是起点。机器人从F出发,走到G可以充电,走到Y关掉开关,D不能走进,要求把所有开关关掉,且电量最少,并求出该最小电量。

把F,G,Y的坐标存起来,然后用bfs求出它们每两个点最短距离,然后用dp判断是不是可以满足目的状态。 用二分枚举答案。

 #include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#define maxn 17
using namespace std;
const int inf=<<; char g[][];
int n,m;
int gg[][];
bool vis[][];
int dir[][]={{,},{-,},{,},{,-}};
int sx,sy;
int spos;
int epos;
int cnt;
int dis[][];
int dp[(<<maxn)][maxn];
struct node
{
int x,y;
}p[],st,st1,st2; int bfs(int s,int t)
{
queue<node>q;
memset(vis,false,sizeof(vis));
for(int i=; i<n; i++)
{
for(int j=; j<m; j++)
{
dis[i][j]=inf;
}
}
dis[p[s].x][p[s].y]=;
st.x=p[s].x;
st.y=p[s].y;
vis[p[s].x][p[s].y]=true;
q.push(st);
while(!q.empty())
{
st1=q.front();
q.pop();
if(st1.x==p[t].x&&st1.y==p[t].y)
{
return dis[st1.x][st1.y];
}
for(int i=; i<; i++)
{
int xx=st1.x+dir[i][];
int yy=st1.y+dir[i][];
if(xx>=&&xx<n&&yy>=&&yy<m&&!vis[xx][yy]&&g[xx][yy]!='D')
{
dis[xx][yy]=dis[st1.x][st1.y]+;
st2.x=xx;
st2.y=yy;
vis[xx][yy]=true;
q.push(st2);
}
}
}
return -;
} int ok(int c)
{
memset(dp,-,sizeof(dp));
dp[<<spos][spos]=c;
for(int i=; i<(<<cnt); i++)
{
for(int j=; j<cnt; j++)
{
if((i&(<<j))==) continue;
if(dp[i][j]==-) continue;
if((i&epos)==epos) return true;
for(int k=; k<cnt; k++)
{
if(i&(<<k)) continue;
if(gg[j][k]==-) continue;
if(dp[i][j]<gg[j][k]) continue;
if(dp[i|(<<k)][k]==-) dp[i|(<<k)][k]=dp[i][j]-gg[j][k];
else dp[i|(<<k)][k]=max(dp[i|(<<k)][k],dp[i][j]-gg[j][k]);
int x1=p[k].x,y1=p[k].y;
if(g[x1][y1]=='G') dp[i|(<<k)][k]=c;
}
}
}
return false;
} int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==&&m==) break;
cnt=;
epos=;
for(int i=; i<n; i++)
{
scanf("%s",g[i]);
for(int j=; j<m; j++)
{
if(g[i][j]=='F')
{
sx=i; sy=j;
spos=cnt;
epos|=(<<cnt);
p[cnt].x=i;
p[cnt++].y=j;
}
if(g[i][j]=='G')
{
p[cnt].x=i;
p[cnt++].y=j;
}
if(g[i][j]=='Y')
{
epos|=(<<cnt);
p[cnt].x=i;
p[cnt++].y=j;
}
}
}
for(int i=; i<cnt; i++)
{
for(int j=; j<cnt; j++)
{
if(i==j) gg[i][j]=;
else gg[i][j]=bfs(i,j);
}
}
int l=,r=n*m;
int mid;
int ans=-;
while(l<=r)
{
mid=(l+r)>>;
if(ok(mid))
{
ans=mid;
r=mid-;
}
else l=mid+;
}
printf("%d\n",ans);
}
return ;
}

hdu 3681 Prison Break的更多相关文章

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

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

  2. hdu 3681 Prison Break (TSP问题)

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

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

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

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

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

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

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

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

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

  7. HDU 3681 Prison Break(状压DP + BFS)题解

    题意:一张图,F是起点,Y是必须要到的点,D不能走,G可以充电.可以往四个方向走,每走一步花费一个电,走到G可以选择充满电或者不充,每个G只能充一次.问你走遍Y的最小初始点亮.number(G) + ...

  8. hdu3511 Prison Break 圆的扫描线

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=3511 题目: Prison Break Time Limit: 10000/5000 MS ( ...

  9. HDU3681 Prison Break

    Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...

随机推荐

  1. [置顶] Android开发之ProcessState和IPCThreadState类分析

    在Android中ProcessState是客户端和服务端公共的部分,作为Binder通信的基础,ProcessState是一个singleton类,每个 进程只有一个对象,这个对象负责打开Binde ...

  2. [网络] SOCKET, TCP/UDP, HTTP, FTP

    (一)TCP/UDP,SOCKET,HTTP,FTP简析 TCP/IP是个协议组,可分为三个层次:网络层.传输层和应用层: 网络层:IP协议.ICMP协议.ARP协议.RARP协议和BOOTP协议 传 ...

  3. 泛泰A870刷4.4专用英文版非触摸CWM Recovery 6.0.4.8(三版通刷)

    首先声明. 发此Recovery的目的是測试能否够三版都能够启动. 而且不会出现像850 860之前出现过的卡第一屏问题! 不希望看到某些人士的过度解读!! 此Recovery能够刷第三方4.4 RO ...

  4. setTimeout()的返回值

    今天遇到一个问题,题目如下: var len=4; while(len--){ setTimeout(function(){ console.log(len); },0); console.log(l ...

  5. Android 自定义View (四) 视频音量调控

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24529807 今天没事逛eoe,看见有人求助要做一个下面的效果,我看下面一哥们说 ...

  6. Java基础知识强化88:BigDecimal类之BigDecimal类引入和概述 以及 BigDecimal的使用(加减乘除)

    1. BigDecimal类概述: 由于在运算的时候,float类型和double很容易丢失精度.所以为了能够精确的表达.计算浮点数,Java提供了BigDecimal. BigDecimal:不可变 ...

  7. html移动端开发注意事项

    meta <meta charset="utf8"> <meta name="viewport" content="width=de ...

  8. 启动android程序报错

    提示错误如下: The connection to adb is down, and a severe error has occured. [2010-03-11 09:36:56 - HelloO ...

  9. Mysql锁机制介绍

    Mysql锁机制介绍 一.概况MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制.比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking ...

  10. 结束指定Activity实例代码

    开通博客两个多月了,一直在看你们的文章 终于发觉伸手党真的很可耻.. 于是就随便写了个Demo来结束伸手党生涯~ Demo很简单:结束指定Activity... 不过也是我的一个小心意嘛.. 不要责怪 ...