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. WaitForSingleObject()

    参见:http://blog.csdn.net/xiaobai1593/article/details/6672193 1. 格式 DWORD WaitForSingleObject( HANDLE  ...

  2. 转载:Erlang 函数(Efficiency Guide)

    转自:http://www.cnblogs.com/futuredo/archive/2012/10/26/2737644.html Functions 1  Pattern matching 模式匹 ...

  3. POJ 3211 Washing Clothes 背包题解

    本题是背包问题,可是须要转化成背包的. 由于是两个人洗衣服,那么就是说一个人仅仅须要洗一半就能够了,由于不能两个人同一时候洗一件衣服,所以就成了01背包问题了. 思路: 1 计算洗完同一颜色的衣服须要 ...

  4. hadoop本地测试命令

    http://www.cnblogs.com/shishanyuan/p/4190403.html if have assign the /etc/profile: hadoop jar /usr/l ...

  5. SQL Server 备份和还原数据库

    备份: --完整备份 ) set @db_name = 'WSS_Content_Test'; ) set @db_location = 'D:\spbr0002\0000000B.bak'; --保 ...

  6. AssetBundle中Unload()方法的作用

    AssetBundle.Unload(false)的作用: 官网的解释是这样的: When unloadAllLoadedObjects is false, compressed file data ...

  7. git 清空所有commit记录方法

    说明:例如将代码提交到git仓库,将一些敏感信息提交,所以需要删除提交记录以彻底清除提交信息,以得到一个干净的仓库且代码不变 1.Checkout git checkout --orphan late ...

  8. 在linux本地下载ftp中的文件

    使用wget命令 -r :会在当前目录下生成192.168.30.14文件名 下面的命令就是下载这个ftp目录"/home/ftp/*"下面的所有文件 wget -r ftp:// ...

  9. 【RF库Collections测试】Dictionary Should Not Contain Key

    Name:Dictionary Should Not Contain KeySource:Collections <test library>Arguments:[ dictionary ...

  10. Zookeeper异常org.apache.zookeeper.KeeperException$ConnectionLossException

    在虚拟机上安装了CenOS Linux系统,然后配置好了 zookeeper的集群环境,在本地写了一个Zookeeper测试程序,如下: package com.xbq.zookeeper; impo ...