ICPC Pacific Northwest Regional Contest 2016 - Buggy Robot(bfs+dp)

You are trying to program a robot to navigate through a 2-dimensional maze and find the exit. 

The maze can be represented as a grid with n rows and m columns. Some grid cells have obstaclesthat the robot cannot pass. The other cells are empty, which the robot can freely pass. Exactly oneof the empty cells in the grid is marked as the exit, and the robot will exit the maze immediatelyonce it reaches there.

You can program the robot by sending it a command string. A command string consists of characters ‘L’, ‘U’, ‘R’, ‘D’, corresponding to the directions left, up, right, down, respectively. The robotwill then start executing the commands, by moving to an adjacent cell in the directions specifiedby the command string. If the robot would run into an obstacle or off the edge of the grid, it willignore the command, but it will continue on to remaining commands. The robot will also ignoreall commands after reaching the exit cell. 

Your friend sent you a draft of a command string, but you quickly realize that the command stringwill not necessarily take the robot to the exit. You would like to fix the string so that the robotwill reach the exit square. In one second, you can delete an arbitrary character, or add an arbitrarycharacter at an arbitrary position. Find how quickly you can fix your friend’s command string. 

You do not care how long it takes the robot to find the exit, but only how long it takes to repairthe command string.

Input

The first line of input contains the two integers n and m (1 ≤ n, m ≤ 50).Each of the next n lines contains m characters, describing the corresponding row of the grid. Emptycells are denoted as ‘.’, the robot’s initial position is denoted as ‘R’, obstacles are denoted as ‘#’,and the exit is denoted as ‘E’.The next and final line of input contains your friend’s command string, consisting of between 1 and50 characters, inclusive.It is guaranteed that the grid contains exactly one ‘R’ and one ‘E’, and that there is always a pathfrom ‘R’ to ‘E’.

Output

Print, on a single line, a single integer indicating the minimum amount of time to fix the program. 

样例输入1复制

3 3
R..
.#.
..E
LRDD

样例输出1复制

1

样例输入2复制

2 4
R.#.
#..E
RRUUDDRRUUUU

样例输出2复制

0

题目链接:点击查看

题目大意:给出一个 n * m 的迷宫,里面有一个起点和一个终点,再给出一条方向指令,机器人会按照指令行走一次,问最少添加或者删除多少个指令字符,可以使得机器人到达终点

题目分析:首先需要知道的是,添加或者删除指令,这两个操作其实是等价的,所以我们只需要考虑添加指令的情况即可,因为删除一个指令,相当于添加这个指令的反向指令

因为是需要求一个最优解,可以考虑 dp ,dp[ x ][ y ][ step ] 表示机器人走到了点 ( x , y ) 到了第 step 条指令时,所需要添加指令的最小个数,转移的话可以类似于 spfa 的思想,对于任意一个状态 ( x , y , step ) ,考虑添加指令的操作,可以向四周扩散一个单位,并且转移最优状态,再考虑按照指令前进一步,那么就是无代价花费,直接转移即可

代码:
 

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
using namespace std;

typedef long long LL;

typedef unsigned long long ull;

const int inf=0x3f3f3f3f;

const int N=60;

const int b[4][2]={0,1,0,-1,1,0,-1,0};

int dp[N][N][N],n,m;

char maze[N][N],s[N],mp[150];

struct Node
{
	int x,y,step;
	Node(int x,int y,int step):x(x),y(y),step(step){}
};

bool check(int x,int y)
{
	return x>0&&y>0&&x<=n&&y<=m&&maze[x][y]!='#';
}

int bfs()
{
	int len=strlen(s+1);
	int ex,ey,sx,sy;
	memset(dp,inf,sizeof(dp));
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(maze[i][j]=='R')
				sx=i,sy=j;
			else if(maze[i][j]=='E')
				ex=i,ey=j;
	queue<Node>q;
	q.push(Node(sx,sy,0));
	dp[sx][sy][0]=0;
	while(q.size())
	{
		Node cur=q.front();
		int x=cur.x,y=cur.y,step=cur.step;
		q.pop();
		for(int i=0;i<4;i++)
		{
			int xx=x+b[i][0];
			int yy=y+b[i][1];
			if(!check(xx,yy))
				continue;
			if(dp[xx][yy][step]>dp[x][y][step]+1)
			{
				dp[xx][yy][step]=dp[x][y][step]+1;
				q.push(Node(xx,yy,step));
			}
		}
		if(step<len)
		{
			int pos=mp[s[step+1]];
			int xx=x+b[pos][0];
			int yy=y+b[pos][1];
			if(!check(xx,yy))
				xx=x,yy=y;
			if(dp[xx][yy][step+1]>dp[x][y][step])
			{
				dp[xx][yy][step+1]=dp[x][y][step];
				q.push(Node(xx,yy,step+1));
			}
		}
	}
	int ans=inf;
	for(int i=0;i<=len;i++)
		ans=min(ans,dp[ex][ey][i]);
	return ans;
}

int main()
{
#ifndef ONLINE_JUDGE
//  freopen("input.txt","r",stdin);
//  freopen("output.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);
	mp['R']=0,mp['L']=1,mp['D']=2,mp['U']=3;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%s",maze[i]+1);
	scanf("%s",s+1);
	printf("%d\n",bfs());


















    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_45458915/article/details/106894436