题目链接: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. CLR_Via_C#学习笔记之事件

    一:首先我先引用网上别人对事件的一些说明,然后将会通过一个事例进行对事件的演示: EventArgs是包含事件数据的类的基类,用于传递事件的细节.EventHandler是一个委托声明如下 publi ...

  2. JavaScript(三)-- DOM编程

    JavaScript编程中最基本的就是DOM编程,DOM是 Document Object Model文本对象模型,就是对DOM对象进行编程的过程. Java语言和Js都有针对于DOM的编程,两者类似 ...

  3. struts2中文件上传

    注意点 private File image;//对应的就是表单中文件上传的那个输入域的名称,Struts2框架会封装成File类型的 private String imageFileName;// ...

  4. hibernate 组件映射

    注解方式:   import javax.persistence.Embedded; import javax.persistence.Entity; import javax.persistence ...

  5. poj3177 Redundant Paths 边双连通分量

    给一个无向图,问至少加入多少条边能够使图变成双连通图(随意两点之间至少有两条不同的路(边不同)). 图中的双连通分量不用管,所以缩点之后建新的无向无环图. 这样,题目问题等效于,把新图中度数为1的点相 ...

  6. 无需超级用户mpi多机运行

    在之前的一篇博文中(Linux下mpi环境配置与运行步骤(Ubuntu为例) ),有讨论过怎样使用MPI在两个不同的机器上运行程序,在那篇博文中使用了超级用户权限.不幸的是.有些情况下,我们不能拥有操 ...

  7. Python: 去掉字符串中的非数字(或非字母)字符

    >>> crazystring = ‘dade142.;!0142f[.,]ad’ 只保留数字>>> filter(str.isdigit, crazystring ...

  8. Archive将多个对象归档到同一个文件

    使用archiveRootObject:toFile:方法能够将一个对象直接写入到一个文件里.但有时候可能想将多个对象写入到同一个文件里,那么就要使用NSData来进行归档对象. NSData能够为一 ...

  9. 问题解决: Pandas and scikit-learn: KeyError: […] not in index

    https://stackoverflow.com/questions/51091132/pandas-and-scikit-learn-keyerror-not-in-index The probl ...

  10. CORS解决WebApi跨域问题(转)

    CORS全称Cross-Origin Resource Sharing,中文全称跨域资源共享.它解决跨域问题的原理是通过向http的请求报文和响应报文里面加入相应的标识告诉浏览器它能访问哪些域名的请求 ...