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. openstack theme topic

  2. nav标签的作用

    . <nav>用来将具有导航性质的链接划分在一起,使代码结构在语义化方面更加准确,同时对于屏幕阅读器等设备的支持也更好.一直以来,我们习惯于使用形如<div id="nav ...

  3. sqlserver2012的审计功能的相关理解

    1.sqlserver2012可以做实例的审计,以及数据库的审计,基本包括了所有的操作.可以符合我们的要求.   2.审计功能需要实例级别的配置数据库级别的配置,实例上建立“审核”,数据库上建立“数据 ...

  4. uboot启动后在内存中运行裸机程序hello

    如题,实现过程中发现3额问题,先写下来,待解答: 1.uboot启动后再dnw上打印许多信息,我想改变其中的打印信息或加上自己的打印信息以证明程序运行到何处.修改完后重新编译uboot.bin. 在D ...

  5. javascript 判断是否是数组

    function isArray(object){ return object && typeof object==='object' && typeof object ...

  6. 跟Google学习Android开发-起始篇-构建你的第一个应用程序(4)

    说明:此系列教程翻译自Google Android开发者官网的Training教程,利用Chome浏览器的自动翻译功能作初译,然后在一些语句不顺或容易造成误解的地方作局部修正.方便英文不好的开发者查看 ...

  7. 第二个参数(那个 properties)确定你将如何使用这个特性值

    CBCharacteristicPropertyBroadcast: 允许一个广播特性值,用于描述特性配置,不允许本地特性 CBCharacteristicPropertyRead: 允许读一个特性值 ...

  8. Tomcat: IllegalStateException: No output folder --reference

    Today, I started to create a couple of JSP pages for the server-side part of my MSc thesis project i ...

  9. Java基础知识强化91:DateFormat类之DateFormat实现日期和字符串的相互转换

    1. DateFormat类概述: DateFormat 是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化并解析日期或时间. 是抽象类,所以使用其子类SimpleDateFormat 2.  ...

  10. 常用PC服务器LSI阵列卡配置

    通常,我们使用的DELL/HP/IBM三家的机架式PC级服务器阵列卡是从LSI的卡OEM出来的,DELL和IBM两家的阵列卡原生程度较高,没有做太多封装,可以用原厂提供的阵列卡管理工具进行监控:而HP ...