Cleaning Robot

Time Limit: 1000MS Memory Limit: 65536K

Total Submissions: 4264 Accepted: 1713

Description

Here, we want to solve path planning for a mobile robot cleaning a rectangular room floor with furniture.

Consider the room floor paved with square tiles whose size fits the cleaning robot (1 * 1). There are ‘clean tiles’ and ‘dirty tiles’, and the robot can change a ‘dirty tile’ to a ‘clean tile’ by visiting the tile. Also there may be some obstacles (furniture) whose size fits a tile in the room. If there is an obstacle on a tile, the robot cannot visit it. The robot moves to an adjacent tile with one move. The tile onto which the robot moves must be one of four tiles (i.e., east, west, north or south) adjacent to the tile where the robot is present. The robot may visit a tile twice or more.

Your task is to write a program which computes the minimum number of moves for the robot to change all ‘dirty tiles’ to ‘clean tiles’, if ever possible.

Input

The input consists of multiple maps, each representing the size and arrangement of the room. A map is given in the following format.

w h

c11 c12 c13 … c1w

c21 c22 c23 … c2w



ch1 ch2 ch3 … chw

The integers w and h are the lengths of the two sides of the floor of the room in terms of widths of floor tiles. w and h are less than or equal to 20. The character cyx represents what is initially on the tile with coordinates (x, y) as follows.

‘.’ : a clean tile

‘*’ : a dirty tile

‘x’ : a piece of furniture (obstacle)

‘o’ : the robot (initial position)

In the map the number of ‘dirty tiles’ does not exceed 10. There is only one ‘robot’.

The end of the input is indicated by a line containing two zeros.

Output

For each map, your program should output a line containing the minimum number of moves. If the map includes ‘dirty tiles’ which the robot cannot reach, your program should output -1.

Sample Input

7 5

…….

.o…*.

…….

..

…….

15 13

…….x…….

…o…x….*..

…….x…….

…….x…….

…….x…….

……………

xxxxx…..xxxxx

……………

…….x…….

…….x…….

…….x…….

..….x…...

…….x…….

10 10

……….

..o…….

……….

……….

……….

…..xxxxx

…..x….

…..x.*..

…..x….

…..x….

0 0

Sample Output

8

49

-1

Source

这道题目有很多解法吧,但是我觉得简单一点就是先BFS算出起点和每个脏的点之间最短距离,然后就是一个简单的TSP问题,用状态压缩DP就可以解决了。我是一遍过了,不免有点小激动呢

#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <queue>
#include <stdio.h> using namespace std;
#define MAX 100000000
int dis[11][11];
int dis2[11];
char a[25][25];
int dp[1<<10][11];
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int vis[25][25];
int st,ed;
bool res;
int n,m;
struct Node
{
int x;
int y;
int num;
}b[11];
queue<Node> q;
int bfs(int x1,int y1,int x2,int y2)
{
Node term1;
term1.x=x1;term1.y=y1;term1.num=0;
vis[x1][y1]=1;
q.push(term1);
while(!q.empty())
{
Node term=q.front();
q.pop();
if(term.x==x2&&term.y==y2)
{
return term.num;
}
for(int i=0;i<4;i++)
{
int xx=term.x+dir[i][0];
int yy=term.y+dir[i][1];
if(xx<1||xx>n||yy<1||yy>m)
continue;
if(a[xx][yy]=='x'||vis[xx][yy])
continue;
vis[xx][yy]=1;
Node temp;temp.x=xx;temp.y=yy;temp.num=term.num+1;
q.push(temp);
} }
return -1;
}
void init()
{
memset(vis,0,sizeof(vis));
while(!q.empty())
q.pop();
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF)
{
if(n==0&&m==0)
break;
res=true;
getchar();
int cot=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%c",&a[i][j]);
if(a[i][j]=='o'){st=i;ed=j;}
else if(a[i][j]=='*'){b[cot].x=i;b[cot++].y=j;}
}
getchar();
}
for(int i=0;i<cot;i++)
{
init();dis2[i]=bfs(st,ed,b[i].x,b[i].y);
if(dis2[i]==-1)
{res=false;break;}
}
if(!res){printf("-1\n");continue;}
for(int i=0;i<cot;i++)
for(int j=i+1;j<cot;j++)
{
init();
dis[i][j]=dis[j][i]=bfs(b[i].x,b[i].y,b[j].x,b[j].y);
}
int state=(1<<(cot))-1;
for(int i=0;i<=state;i++)
for(int j=0;j<cot;j++)
dp[i][j]=MAX;
for(int i=0;i<cot;i++)
dp[1<<i][i]=dis2[i];
for(int i=1;i<=state;i++)
{
for(int j=0;j<cot;j++)
{
if(!((1<<j)&i))
continue;
for(int k=0;k<cot;k++)
{
if(k==j) continue;
if((1<<k)&i) continue;
int ss=i+(1<<k);
dp[ss][k]=min(dp[ss][k],dp[i][j]+dis[j][k]);
}
}
}
int ans=MAX;
for(int i=0;i<cot;i++)
ans=min(ans,dp[state][i]);
printf("%d\n",ans);
}
return 0; }

HOJ 2226&POJ2688 Cleaning Robot(BFS+TSP(状态压缩DP))的更多相关文章

  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. BFS+优先队列+状态压缩DP+TSP

    http://acm.hdu.edu.cn/showproblem.php?pid=4568 Hunter Time Limit: 2000/1000 MS (Java/Others)    Memo ...

  3. TSP - 状态压缩dp

    2017-08-11 21:10:21 艾教写的 #include<iostream> #include<cstdio> #include<cstring> #in ...

  4. BFS+状态压缩DP+二分枚举+TSP

    http://acm.hdu.edu.cn/showproblem.php?pid=3681 Prison Break Time Limit: 5000/2000 MS (Java/Others)   ...

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

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

  6. HDU 3247 Resource Archiver (AC自己主动机 + BFS + 状态压缩DP)

    题目链接:Resource Archiver 解析:n个正常的串.m个病毒串,问包括全部正常串(可重叠)且不包括不论什么病毒串的字符串的最小长度为多少. AC自己主动机 + bfs + 状态压缩DP ...

  7. TSP 旅行商问题(状态压缩dp)

    题意:有n个城市,有p条单向路径,连通n个城市,旅行商从0城市开始旅行,那么旅行完所有城市再次回到城市0至少需要旅行多长的路程. 思路:n较小的情况下可以使用状态压缩dp,设集合S代表还未经过的城市的 ...

  8. 学习笔记:状态压缩DP

    我们知道,用DP解决一个问题的时候很重要的一环就是状态的表示,一般来说,一个数组即可保存状态.但是有这样的一些题 目,它们具有DP问题的特性,但是状态中所包含的信息过多,如果要用数组来保存状态的话需要 ...

  9. 状态压缩DP(大佬写的很好,转来看)

    奉上大佬博客 https://blog.csdn.net/accry/article/details/6607703 动态规划本来就很抽象,状态的设定和状态的转移都不好把握,而状态压缩的动态规划解决的 ...

随机推荐

  1. imx6 spi分析

    /************************************************************************** *本文主要跟踪imx6 spi设备和驱动的注册过 ...

  2. Spring Boot集成Mybatis及通用Mapper

    集成Mybatis可以通过 mybatis-spring-boot-starter 实现. <!-- https://mvnrepository.com/artifact/org.mybatis ...

  3. 详解JNDI的lookup资源引用 java:/comp/env

    ENC的概念:     The application component environment is referred to as the ENC, the enterprise naming c ...

  4. javascript中call、apply、argument、callee、caller

    1.Call方法 调用一个对象的一个方法,以另一个对象替换当前对象. call([thisObj[,arg1[, arg2[, [,.argN]]]]]) thisObj 可选项.将被用作当前对象的对 ...

  5. js上传本地图片遇到的问题

    1.改变页面文件上传默认的样式 <input type="text" size="20" id="upfile" style=&quo ...

  6. MathType编辑双向斜箭头的教程

    箭头是一个很常见的符号,不只是在数学中,在各个方面出现的频率都很高,因此在数学公式中出现时,用MathType公式编辑器编辑公式时也要尽量地能够编辑出这些符号.箭头符号在MathType中有很多,使用 ...

  7. 如何用MathType编辑化学等式

    MathType在数学中应用非常广泛,被大量用于编辑数学公式,MathType不仅可以用来编辑数学公式,还可以编辑化学反应式,那么MathType编辑化学等式怎么操作的呢? 具体操作如下: 1.打开M ...

  8. win10取消开机密码

    WIN10开机以后点击一下[开始]然后面它的搜索栏处输入[netplwiz]就可以看到如下图所示提示.   进入到用户长户界面,把[要使用本计算机,用户必须输入用户名和密码]前面的那个勾勾取消了,再点 ...

  9. HE算法与Scaler算法

    HE算法:图像直方图均衡化 Scaler算法:图像缩放 基于matab的scaler实现_图文_百度文库 https://wenku.baidu.com/view/016f5e4002768e9951 ...

  10. 创建ros的程序包--3

    创建ros的程序包(原创博文,转载请标明出处--周学伟http://www.cnblogs.com/zxouxuewei/) 1.一个catkin程序包由什么组成? 一个程序包要想称为catkin程序 ...