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. C#.net实现密码加密算法

    //SHA-1算法string password = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFil ...

  2. XCode7中不能使用http的临时配置解决办法

    先看看iOS9新特性中关于ATS的官方文档: App Transport Security App Transport Security (ATS) enforces best practices i ...

  3. poj 3229 The Best Travel Design ( 图论+状态压缩 )

    The Best Travel Design Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 1359   Accepted: ...

  4. 招一位安防软件project师,嵌入式开发project师

    岗位职责 1.负责海思平台IPC产品应用层软件设计及维护 2.私有平台协议对接及为第三方提供技术支持. 任职资格: 1.较强的学习.领悟能力,能够高速熟悉公司现有代码. 2.熟练掌握C.C++开发语言 ...

  5. jQuery 對table的基本操作

    一.鼠标移动到行更换背景色: css样式: .hover{ background-color: #cccc00; } Js脚本: $(document).ready(function () { //鼠 ...

  6. 使用Httpwatch分析响应时间--转

    时间片段名称 意思 Blocked (阻塞)灰色 阻塞的时间主要包括,预处理时间,(如缓存查找)和网络排队等待的时间,导致阻塞最主要的原因是下载页面中的图片 DNS Lookup(域名解释)紫色 域名 ...

  7. 修改用户的home路径

    1.直接修改/etc/passwd文件 2.usermod -d /hadoop -u 1531 附:usermod详细参数 语 法:usermod [-LU][-c <备注>][-d & ...

  8. activiti总结2

    根据流程号查询失败原因. activiti重试机制.齿轮节点.邮件节点.任务节点.ACT_HI_ACTINST历史表.ACT_RU_EXECUTION运行表.看图. 在Eclipse里面自己写个测试方 ...

  9. 怎样成为PHP 方向的一个合格的架构师

    突然看到这篇文章, 值得反省, 乐在其中, 在接下来的发展中不被淘汰的都来看看, 如何成为一个架构师先明确这里所指的PHP工程师,是指主要以PHP进行Web系统的开发,没有使用其的语言工作过.工作经验 ...

  10. Android学习手记(6) TabActivity和TabHost

    使用TabHost可以实现标签式效果,将两个Activity放在两个Tab内. 首先,需要基于MainActivity创建一个TabHost对象. TabHost tabHost = this.get ...