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. 《算法问题实战策略》-chaper32-网络流

    基本的网络流模型: 在图论这一块初步的应用领域中,两个最常见的关注点,其一时图中的路径长度,也就是我们常说的的最短路径问题,另一个则是所谓的“流问题”. 流问题的基本概念: 首先给出一张图. 其实所谓 ...

  2. 【Python排序搜索基本算法】之Prim算法

    Prim算法是实现最简单的最小生成树(MST)算法,适合于稠密图.要实现Prim算法,我们主要关注的是增量的变化,也就是从每个非树顶点到树顶点的最短距离,使得最后生成一棵包括所有顶点的树,并且这棵树的 ...

  3. sts 去掉启动的rss功能

    STS(spring tools suite) 每次开启都显示,比较烦人,可以在设置中禁用掉,具体方法:window->Perferences,然后查找dashboard,将启动时展示dashb ...

  4. oracle的shutdown命令有几种参数

    SHUTDOWN NORMAL:不允许新的连接.等待会话结束.等待事务结束.做一个检查点并关闭数据文件.启动时不需要实例恢复.SHUTDOWN TRANSACTIONAL:不允许新的连接.不等待会话结 ...

  5. 学习之路十四:客户端调用WCF服务的几种方法小议

    最近项目中接触了一点WCF的知识,也就是怎么调用WCF服务,上网查了一些资料,很快就搞出来,可是不符合头的要求,主要有以下几个方面: ①WCF的地址会变动,地址虽变,但是里面的逻辑不变! ②不要引用W ...

  6. webpy:页面下载的三种实现方式

    python: 1.import urllib urlretrieve() 方法直接将远程数据下载到本地. >>> help(urllib.urlretrieve)Help on f ...

  7. spring-junit的标注总结

    如果在测试类的类名上面添加了注解 @ContextConfiguration("meta/springConfigured.xml") 如何在标注了@Test的方法里面获取上面xm ...

  8. Wcf简单实例1

    一.客户端添加服务引用,并调用 1.使用客户端代理同步调用 static void TestTwo() { /*********同步访问********/ Person.PersonServiceCl ...

  9. 如何分析apache日志[access_log(访问日志)和error_log(错误日志)]

    如何分析apache日志[access_log(访问日志)和error_log(错误日志)] 发布时间: 2013-12-17 浏览次数:205 分类: 服务器 默认Apache运行会access_l ...

  10. Windows Server 2003 SP2 R2 企业版/标准版/32与64位 CD-KEY

    微软发布Windows Server 2003 R2版的目的是希望透过它填补Windows Server 2003 SP1和Longhorn Server之间的产品发布时间间隔.所以Windows S ...