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. 第三百零三节,Django框架介绍——用pycharm创建Django项目

    Django框架介绍 Django是一个开放源代码的Web应用框架,由Python写成.采用了MVC的软件设计模式,即模型M,视图V和控制器C.它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内 ...

  2. (转)typedef 函数指针的用法

    typedef 函数指针的用法   在网上搜索函数指针,看到一个例子.开始没看懂,想放弃,可是转念一想,这个用法迟早要弄懂的,现在多花点时间看懂它,好过以后碰到了要再花一倍时间来弄懂它.其实很多时候都 ...

  3. CentOS下的一些基础问题解答

    1. 在/etc/passwd中某一行信息为“Linux01:x:505:505:/home/linux12:/bin/bash”,由此可知哪些信息? 用户名为linux01,需要密码登陆,用户ID为 ...

  4. php中ignore_user_abort函数的用法(定时)

    PHP中的ignore_user_abort函数是当用户关掉终端后脚本不停止仍然在执行,可以用它来实现计划任务与持续进程,下面会通过实例讨论ignore_user_abort()函数的作用与用法. i ...

  5. 使用PHP生成和获取XML格式数据

    1.php生成xml

  6. Java基础--生成验证码

    HTML <%@ page language="java" contentType="text/html; charset=UTF-8" pageEnco ...

  7. SQL-字符串连接聚合函数

    原文:http://blog.csdn.net/java85140031/article/details/6820699 问题: userId  role_name         role_id 1 ...

  8. windows,cmd中,如何切换到磁盘的根目录下

    需求描述: 在windows的cmd中操作,有的时候也会遇到切换了很多的目录,然后需要切换到根目录的情况 操作过程: 1.通过cd \的方式,切换回当前磁盘的根目录下 备注:未切换之前,在Driver ...

  9. mongoDB在windows64上安装

    1.下载64位:mongodb-win32-x86_64-enterprise-windows-64-2.6.4-signed.msi 2.安装目录:将应用安装到此目录下面:C:\MongoDB\ 3 ...

  10. C++11新特性之八——函数对象function

    详细请看<C++ Primer plus>(第六版中文版) http://www.cnblogs.com/lvpengms/archive/2011/02/21/1960078.html ...