也算难题,难在如何处理有些点可以无限次经过 问题。 这道题,其实很容易想到二分+TSP的状态压缩,但在处理上述问题时,确实没想到。题解是处理每一个Y或G或F点到其他YGF点的距离,BFS,这样就出现一个点只访问一次,而且即便在原图上重复经过某点,在重建的图也不会体现出来了。绝!

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; char map[16][16];
bool vis[16][16];
int cnt,dp[1<<16][16];
struct Node{
int x,y;
}node[16];
int dis[16][16][16][16];
const int inf=(1<<30);
int n,m,fp,head,tail;
int dir[4][2]={
{0,1},
{0,-1},
{1,0},
{-1,0}
};
Node que[400];
int endfor; bool ok(int x,int y){
if(x>=0&&x<n&&y>=0&&y<m&&map[x][y]!='D'&&!vis[x][y]) return true;
return false;
} void bfs(Node start){
Node tmp;
vis[start.x][start.y]=true;
que[tail++]=start;
int step=0;
while(head<tail){
int sz=tail-head;
step++;
while(sz--){
Node ss=que[head++];
for(int i=0;i<4;i++){
tmp.x=ss.x+dir[i][0];
tmp.y=ss.y+dir[i][1];
if(ok(tmp.x,tmp.y)){
if(map[tmp.x][tmp.y]=='G'||map[tmp.x][tmp.y]=='Y'){
dis[start.x][start.y][tmp.x][tmp.y]=step;
// cout<<start.x<<" "<<start.y<<" "<<tmp.x<<" "<<tmp.y<<" "<<step<<endl;
}
que[tail++]=tmp;
vis[tmp.x][tmp.y]=true;
}
}
}
}
} bool check(int bat){
memset(dp,-1,sizeof(dp));
int alt=1<<cnt;
dp[1<<fp][fp]=bat;
for(int i=0;i<alt;i++){
for(int j=0;j<cnt;j++){
if(dp[i][j]==-1) continue;
if((i&endfor)==endfor){
if(dp[i][j]!=-1) return true;
}
for(int k=0;k<cnt;k++){
if(dis[node[j].x][node[j].y][node[k].x][node[k].y]==-1) continue;
if(i&(1<<k)) continue;
if(dp[i][j]-dis[node[j].x][node[j].y][node[k].x][node[k].y]<0) continue;
int tmp=dp[i][j]-dis[node[j].x][node[j].y][node[k].x][node[k].y];
if(map[node[k].x][node[k].y]=='G') tmp=bat;
if(tmp>dp[i|(1<<k)][k]) dp[i|(1<<k)][k]=tmp;
}
}
}
return false;
} void slove(){
int l=0,r=1000;
int res=r;
while(l<=r){
int m=(l+r)/2;
if(check(m)){
res=m;
r=m-1;
}
else l=m+1;
}
if(res==1000) printf("-1\n");
else printf("%d\n",res);
} int main(){
while(scanf("%d%d",&n,&m),n||m){
cnt=0;
endfor=0;
for(int i=0;i<n;i++){
scanf("%s",map[i]);
// cout<<map[i]<<endl;
for(int j=0;j<m;j++){
if(map[i][j]=='F'){
fp=cnt;
node[cnt].x=i,node[cnt].y=j;
cnt++;
}
else if(map[i][j]=='G'){
node[cnt].x=i,node[cnt].y=j;
cnt++;
}
else if(map[i][j]=='Y'){
node[cnt].x=i,node[cnt].y=j;
endfor+=(1<<cnt);
cnt++;
}
}
}
memset(dis,-1,sizeof(dis));
for(int i=0;i<cnt;i++){
head=tail=0;
memset(vis,false,sizeof(vis));
bfs(node[i]);
}
slove();
}
return 0;
}

  

HDU 3681的更多相关文章

  1. HDU 3681 Prison Break(状态压缩dp + BFS)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3681 前些天花时间看到的题目,但写出不来,弱弱的放弃了.没想到现在学弟居然写出这种代码来,大吃一惊附加 ...

  2. hdu 3681 Prison Break

    http://acm.hdu.edu.cn/showproblem.php?pid=3681 题意:一个n*m的矩阵,'F'是起点.机器人从F出发,走到G可以充电,走到Y关掉开关,D不能走进,要求把所 ...

  3. hdu 3681(bfs+二分+状压dp判断)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3681 思路:机器人从出发点出发要求走过所有的Y,因为点很少,所以就能想到经典的TSP问题.首先bfs预 ...

  4. HDU 3681 Prison Break(BFS+二分+状态压缩DP)

    Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But one da ...

  5. hdu 3681 Prison Break (TSP问题)

    Prison Break Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot ...

  6. hdu 3681 Prison Break(状态压缩+bfs)

    Problem Description Rompire . Now it’s time to escape, but Micheal# needs an optimal plan and he con ...

  7. HDU 3681 BFS&amp;像缩进DP&amp;二分法

    N*M矩阵.从F出发点.走完全部Y点.每个人格开支1电源点,去G点,电池充满,D无法访问.最小的开始问什么时候满负荷可以去完全部Y.Y和G总共高达15一 第一BFS所有的F.Y.G之间的最短距离. 然 ...

  8. HDU 3681 Prison Break (二分 + bfs + TSP)

    题意:给定上一个 n * m的矩阵,你的出发点是 F,你初始有一个电量,每走一步就会少1,如果遇到G,那么就会加满,每个G只能第一次使用,问你把所有的Y都经过,初始电量最少是多少. 析:首先先预处理每 ...

  9. hdu 3681 压缩dp+搜索

    题意:一个机器人想越狱,他只能带一定电量的电池,'S'表示道路可行,'G'表示充电器, 只可充电一次,但是可以经过很多次.'F'表示起点,'Y'表示要破坏的机关,也是只能破坏一次,但是可以经过无数次. ...

  10. HDU 3681 Prison Break 越狱(状压DP,变形)

    题意: 给一个n*m的矩阵,每个格子中有一个大写字母,一个机器人从‘F’出发,拾取所有的开关‘Y’时便能够越狱,但是每走一格需要花费1点能量,部分格子为充电站‘G’,每个电站只能充1次电.而且部分格子 ...

随机推荐

  1. asp.net core 2.0 Json结果的格式

    asp.net core 2.0 默认返回的结果格式是Json, 并使用json.net对结果默认做了camel case的转化(大概可理解为首字母小写). 这一点与老.net web api 不一样 ...

  2. “国家队爷”杯液体战争AI比赛!!__SymenYang

    原帖 这两天一直在搞这个AI,提供的样例更本不是我的风格啊,看不懂更不会改... 所以我自己写了一个AI的平台,现在在不断的修改AI的策略,smart样例还是很容易过的,让line的行走速度变慢一点到 ...

  3. Android O Bitmap 内存分配

      我们知道,一般认为在Android进程的内存模型中,heap分为两部分,一部分是native heap,一部分是Dalvik heap(实际上也是native heap的一部分).   Andro ...

  4. 六时车主 App iOS隐私政策

    本应用尊重并保护所有使用服务用户的个人隐私权.为了给您提供更准确.更有个性化的服务,本应用会按照本隐私权政策的规定使用和披露您的个人信息.但本应用将以高度的勤勉.审慎义务对待这些信息.除本隐私权政策另 ...

  5. Android中ViewPager动态创建的ImageView铺满屏幕

    ImageView imageView=new ImageView(context); imageView.setScaleType(ScaleType.FIT_XY);//铺满屏幕

  6. STL_string用法总结

    参考自:http://blog.csdn.net/y990041769/article/details/8763366 1:string对象的定义和初始化以及读写 string s1;      默认 ...

  7. day02 python

    列表: : 在[ ]内,可以存放多个任意类型的值: 并以逗号隔开. 一般用于存放学生的爱好:课堂的周期等等... 例如: 定义一个学生列表,可存放多个学生 list(['钱垚', '李小龙', '张全 ...

  8. 创建全局函数 匹配查找 std::map

    std::map<CString, CString> m_NameToType; 所有文件之外声明一个函数 在要用到的地方  加入存储的东西 extern std::map<CStr ...

  9. jquery spa

    1.hashchange监听 2.根据url加载不同页面 $.ajax({ url:"/xx/xx.html" type:"get", dataType:&qu ...

  10. Cashier (codeforces 1059A)

    题目倒是不难注意第一个时间段可能不是从零开始的,所以注意第一个时间的开始节点与零之间可能存在休息的时间 还有这个题我打的时候一直谜之RE......发现原来bool函数忘记写return了.....以 ...