题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3681

思路:机器人从出发点出发要求走过所有的Y,因为点很少,所以就能想到经典的TSP问题。首先bfs预处理出‘Y',’F','G'之间的最短距离,由于G点可以充电,到达G点就把当前能量更新为电池容量然后继续走。因为每个G点只能充一次电,这就好像TSP中的每个点只能走一次一样,然后就是二分答案了,用状压DP判定当前电池容量的情况下是否能符合条件。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std; struct Node{
int x,y;
}node[*]; int dist[][][][];
int dp[<<][];
int n,m,state,final_state,start;
char map[][];
int dir[][]={{-,},{,},{,-},{,}}; void bfs(Node &node)
{
queue<pair<int,int> >que;
que.push(make_pair(node.x,node.y));
dist[node.x][node.y][node.x][node.y]=;
while(!que.empty()){
int x=que.front().first,y=que.front().second;
que.pop();
for(int i=;i<;i++){
int xx=x+dir[i][],yy=y+dir[i][];
if(xx>=&&xx<n&&yy>=&&yy<m&&map[xx][yy]!='D'){
if(dist[node.x][node.y][xx][yy]==-){
dist[node.x][node.y][xx][yy]=dist[node.x][node.y][x][y]+;
que.push(make_pair(xx,yy));
}
}
}
}
} bool Judge(int Power)
{
memset(dp,-,sizeof(dp));
dp[(<<start)][start]=Power;
int res=-;
for(int i=;i<(<<state);i++){
for(int j=;j<state;j++){
if((i&(<<j))==)continue;
if(dp[i][j]<)continue;
if(((i&final_state)&final_state)==final_state)res=max(res,dp[i][j]);
for(int k=;k<state;k++){
if((i&(<<k))||(j==k))continue;
if(dist[node[j].x][node[j].y][node[k].x][node[k].y]<)continue;
if(dp[i][j]-dist[node[j].x][node[j].y][node[k].x][node[k].y]<)continue;
dp[i|(<<k)][k]=max(dp[i|(<<k)][k],dp[i][j]-dist[node[j].x][node[j].y][node[k].x][node[k].y]);
if(map[node[k].x][node[k].y]=='G')dp[i|(<<k)][k]=Power;
}
}
}
return res>=;
} int main()
{
int low,high,mid,ans;
while(~scanf("%d%d",&n,&m)){
if(n==&&m==)break;
state=;
final_state=;
for(int i=;i<n;i++){
scanf("%s",map[i]);
for(int j=;j<m;j++){
if(map[i][j]=='F'){
start=state;
node[state].x=i,node[state].y=j;
final_state|=(<<state);
state++;
}else if(map[i][j]=='G'){
node[state].x=i,node[state++].y=j;
}else if(map[i][j]=='Y'){
node[state].x=i,node[state].y=j;
final_state|=(<<state);
state++;
}
}
}
memset(dist,-,sizeof(dist));
for(int i=;i<state;i++){
bfs(node[i]);
}
low=,high=,ans=-;
while(low<=high){
mid=(low+high)>>;
if(Judge(mid)){
ans=mid;
high=mid-;
}else
low=mid+;
}
printf("%d\n",ans);
}
return ;
}

hdu 3681(bfs+二分+状压dp判断)的更多相关文章

  1. hdu 3247 AC自动+状压dp+bfs处理

    Resource Archiver Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Ot ...

  2. hdu 2825 aC自动机+状压dp

    Wireless Password Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  3. HDU 5765 Bonds(状压DP)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5765 [题目大意] 给出一张图,求每条边在所有边割集中出现的次数. [题解] 利用状压DP,计算不 ...

  4. hdu 4778 Gems Fight! 状压dp

    转自wdd :http://blog.csdn.net/u010535824/article/details/38540835 题目链接:hdu 4778 状压DP 用DP[i]表示从i状态选到结束得 ...

  5. HDU 4272 LianLianKan(状压DP)题解

    题意:一个栈,每次可以选择和栈顶一样的数字,并且和栈顶距离小于6,然后同时消去他们,问能不能把所有的数消去 思路:一个数字最远能消去和他相距9的数,因为中间4个可以被他上面的消去.因为还要判断栈顶有没 ...

  6. HDU 4272 LianLianKan (状压DP+DFS)题解

    思路: 用状压DP+DFS遍历查找是否可行.假设一个数为x,那么他最远可以消去的点为x+9,因为x+1~x+4都能被他前面的点消去,所以我们将2进制的范围设为2^10,用0表示已经消去,1表示没有消去 ...

  7. HDU 3362 Fix (状压DP)

    题意:题目给出n(n <= 18)个点的二维坐标,并说明某些点是被固定了的,其余则没固定,要求添加一些边,使得还没被固定的点变成固定的, 要求总长度最短. 析:由于这个 n 最大才是18,比较小 ...

  8. HDU 3001 Travelling (状压DP,3进制)

    题意: 给出n<=10个点,有m条边的无向图.问:可以从任意点出发,至多经过同一个点2次,遍历所有点的最小费用? 思路: 本题就是要卡你的内存,由于至多可经过同一个点2次,所以只能用3进制来表示 ...

  9. HDU 2923 Relocation(状压dp+01背包)

    题目代号:HDU2923 题目链接:http://poj.org/problem?id=2923 Relocation Time Limit: 1000MS Memory Limit: 65536K ...

随机推荐

  1. Android性能优化典范(一)

    2015年伊始,Google发布了关于Android性能优化典范的专题,一共16个短视频,每个3-5分钟,帮助开发者创建更快更优秀的Android App.课程专题不仅仅介绍了Android系统中有关 ...

  2. Java中Object转化为int类型

    转自:http://blog.sina.com.cn/s/blog_5f8421fb010162kb.html Java中由Object类型转化为int类型时,不能直接转化,先是将Object类型转化 ...

  3. Java中abstract class 和 interface 的解释和他们的异同点(转)

    (一)概述    在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制.正是由于这两种机制的存 在,才赋予了Java强大的 面向对象能力.abstract ...

  4. Timer使用

    1. Timer简介 Timer是jdk中提供的一个定时器工具,使用的时候会在主线程之外起一个单独的线程执行指定的计划任务,可以指定执行一次或者反复执行多次. 通过创建Timer对象,然后调用Time ...

  5. Linux I/O复用中select poll epoll模型的介绍及其优缺点的比較

    关于I/O多路复用: I/O多路复用(又被称为"事件驱动"),首先要理解的是.操作系统为你提供了一个功能.当你的某个socket可读或者可写的时候.它能够给你一个通知.这样当配合非 ...

  6. 强大的Vivado IP工具——自定义IP的使用

    首先,要指出,本文不描述任何IP的功能与使用.   在开发一个大型FPGA项目时,多人协作是必不可少的.这个时候,如何提交设计给负责集成的人,是项目开发中最关键的问题之一. 常用的一个方法是,提交网表 ...

  7. Sublime Text 2/3如何支持中文GBK编码(亲测实现)

    Sublime Text 2/3如何支持中文GBK编码 听语音 | 浏览:17594 | 更新:2014-03-17 10:52 1 2 3 4 5 分步阅读 Sublime Text默认是只支持UT ...

  8. Sublime Text 2中自定义代码模板

    Sublime Text 2中自定义代码模板 2012-12-06 10:13 9921人阅读 评论(0) 收藏 举报  分类: 编辑器-Sublime Text 2(5)  版权声明:本文为博主原创 ...

  9. [容器]docker创建镜像

    手动创建: docker run -d -p mynginx:v2 nginx rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest- ...

  10. python之pilow验证码

    pilow的基本操作 """ Created on Fri Jun 1 12:36:38 2018 @author: Frank """ f ...