HOJ 2226&POJ2688 Cleaning Robot(BFS+TSP(状态压缩DP))
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))的更多相关文章
- HDU 3681 Prison Break(BFS+二分+状态压缩DP)
Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But one da ...
- BFS+优先队列+状态压缩DP+TSP
http://acm.hdu.edu.cn/showproblem.php?pid=4568 Hunter Time Limit: 2000/1000 MS (Java/Others) Memo ...
- TSP - 状态压缩dp
2017-08-11 21:10:21 艾教写的 #include<iostream> #include<cstdio> #include<cstring> #in ...
- BFS+状态压缩DP+二分枚举+TSP
http://acm.hdu.edu.cn/showproblem.php?pid=3681 Prison Break Time Limit: 5000/2000 MS (Java/Others) ...
- HDU 3681 Prison Break(状态压缩dp + BFS)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3681 前些天花时间看到的题目,但写出不来,弱弱的放弃了.没想到现在学弟居然写出这种代码来,大吃一惊附加 ...
- HDU 3247 Resource Archiver (AC自己主动机 + BFS + 状态压缩DP)
题目链接:Resource Archiver 解析:n个正常的串.m个病毒串,问包括全部正常串(可重叠)且不包括不论什么病毒串的字符串的最小长度为多少. AC自己主动机 + bfs + 状态压缩DP ...
- TSP 旅行商问题(状态压缩dp)
题意:有n个城市,有p条单向路径,连通n个城市,旅行商从0城市开始旅行,那么旅行完所有城市再次回到城市0至少需要旅行多长的路程. 思路:n较小的情况下可以使用状态压缩dp,设集合S代表还未经过的城市的 ...
- 学习笔记:状态压缩DP
我们知道,用DP解决一个问题的时候很重要的一环就是状态的表示,一般来说,一个数组即可保存状态.但是有这样的一些题 目,它们具有DP问题的特性,但是状态中所包含的信息过多,如果要用数组来保存状态的话需要 ...
- 状态压缩DP(大佬写的很好,转来看)
奉上大佬博客 https://blog.csdn.net/accry/article/details/6607703 动态规划本来就很抽象,状态的设定和状态的转移都不好把握,而状态压缩的动态规划解决的 ...
随机推荐
- 【转】【VC】VC程序运行时间测试函数
1:Sleep函数 使用: sleep(1000),在Windows和Linux下1000代表的含义并不相同,Windows下的表示1000毫秒,也就是1秒钟: Linux下表示1000秒,Linux ...
- 第二百八十九节,MySQL数据库-ORM之sqlalchemy模块操作数据库
MySQL数据库-ORM之sqlalchemy模块操作数据库 sqlalchemy第三方模块 sqlalchemysqlalchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API ...
- WaitForSingleObject()
参见:http://blog.csdn.net/xiaobai1593/article/details/6672193 1. 格式 DWORD WaitForSingleObject( HANDLE ...
- hdu2147 kiki's game(博弈)
这个是纳什博弈?不知道怎么看的 依据PN图,从左下角開始推 左下角P 最后一行都是PNPNPN 第一列都是 P N P N P 完了填完即可了 #include<cstdio> int m ...
- 最短路径问题-Floyd算法
概念 最短路径也是图的一个应用,即寻找图中某两个顶点的最短路径长度. 实际应用:例如确定某两个城市间的坐火车最短行车路线长度等. Floyd algorithm 中文名就是弗洛伊德算法. 算法思路:用 ...
- 【matlab】图像去噪的代码测试
%% 自己设置频域的滤波窗口 girl=imread('F:\Users\*****\Pictures\CGS_stripe1.bmp'); girl=rgb2gray(girl); girl=im2 ...
- MFC中控件添加了变量后修改
新增一个变量这个变量存在于两个位置,一个是头文件中项目名+Dlg.h文件,另一个是源文件中项目名+Dlg.cpp文件
- fireworks切图
下载安装完成后打开软件 打开一张图片 首选参数的撤销次数改成999 按住空格键 鼠标会变成小手的形状 这时候可以拖拽图像 找到切片工具 记住缩放比例的快捷键 ctrl+空格 放大某个区域 切的时候按住 ...
- 超全面的JavaWeb笔记day02<CSS&JavaScript>
1.CSS的简介 2.CSS概述和与HTML的结合方式(四种)(*******) 3.CSS的基本选择器(******) 4.CSS的扩展选择器(了解) 5.CSS的盒子模型(了解) 6.CSS的布局 ...
- Effective C++ Item 13 Use object to manage resources
1. Always use object to manage resource! If you delete a pointer or release a handler manually by yo ...