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. LANG=C是最早最简单的C语言环境(标准ASCII码)

    LANG=C是最早最简单的C语言环境(标准ASCII码)

  2. QFII

    QFII(Qualified Foreign Institutional Investors)合格的境外机构投资者的英文简称,中文“酋匪”,QFII机制是指外国专业投资机构到境内投资的资格认定制度. ...

  3. Java容器详解

    线性表,链表,哈希表是常用的数据结构,在进行Java开发时,JDK已经为我们提供了一系列相应的类来实现基本的数据结构.这些类均在java.util包中.在Java中,容器的类型主要有:List.Set ...

  4. jsp servelet

    servlet是java web应用程序. 1.生命周期:init() .service().destroy()方法. 其中service()包括 doGet() .doPost()方法.默认为get ...

  5. NSString去掉火车和空格

    //    backString = [backString stringByReplacingOccurrencesOfString:@"\r" withString:@&quo ...

  6. 建立企业内部mavenserver并使用Android Studio公布公共项目

    由于Android Studio使用了Gradle构建工具,在library依赖的处理上是将被依赖的library作为一个module引入(拥有一份完整的library拷贝),而Eclipse的ADT ...

  7. Android之Notification的多种用法

    我们在用手机的时候,如果来了短信,而我们没有点击查看的话,是不是在手机的最上边的状态栏里有一个短信的小图标提示啊?你是不是也想实现这种功能呢?今天的Notification就是解决这个问题的. 我们也 ...

  8. [转] boost::any的用法、优点和缺点以及源代码分析

    boost::any用法示例: #include <iostream> #include <list> #include <boost/any.hpp> typed ...

  9. centos6 Cacti部署文档

    centos6 Cacti部署文档 1.安装依赖 yum -y install mysql mysql-server mysql-devel httpd php php-pdo php-snmp ph ...

  10. html01基本标签

    01. <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8 ...