题意:给一个图,有起点终点,有障碍物。给了一段移动的顺序,可以任意增加删除方向,问最少改几次,能让机器人到终点。
思路:
因为问的是最少修改次数,那么我们就dp它,dp[i] [j] [k] , j , k 是 位置 , i 是执行到第 i 步 , dp值记录最少操作次数。
每次向下推的时候,我们可以在中间插入一个字符,这样就能任意走 四个 方向的方块。
每次删除操作串里的一个字符,那么下一个方向的dp值可以和上一个 取min。
const int Maxn = 1e6 + 7;
const int Inf = 1e9 + 7;
int N , M , len , sx , sy , ex, ey;
char S[55][55];
char op[55];
int dp[55][55][55];
int dx[4] = { 1 , -1 , 0 , 0 };
int dy[4] = { 0 , 0 , 1 , -1 };
struct node{
int x , y , st;
};
queue <node> que;
int mp[256];
void Bfs(){
while(!que.empty()) que.pop();
dp[0][sx][sy] = 0;
que.push((node){sx , sy , 0});
node q;
int x , y , w;
while(!que.empty()){
q = que.front(); que.pop();
for(int i = 0 ; i < 4 ; i++){
x = q.x + dx[i] , y = q.y + dy[i] , w = q.st;
if(x > 0 && x <= N && y > 0 && y <= M && S[x][y] != '#'){
if(dp[w][x][y] > dp[q.st][q.x][q.y] + 1){
dp[w][x][y] = dp[q.st][q.x][q.y] + 1;
que.push((node){x , y , w});
}
}
}
x = q.x , y = q.y , w = q.st;
if(w < len){
if(dp[w+1][x][y] > dp[w][x][y] + 1){
dp[w+1][x][y] = dp[w][x][y] + 1;
que.push((node){x , y , w+1});
}
x = q.x + dx[mp[op[w]]] , y = q.y + dy[mp[op[w]]];
if(x > 0 && x <= N && y > 0 && y <= M && S[x][y] != '#');
else x = q.x , y = q.y;
if(dp[w+1][x][y] > dp[w][q.x][q.y]){
dp[w+1][x][y] = dp[w][q.x][q.y];
que.push((node){x , y , w+1});
}
}
}
}
int main()
{
mp['D'] = 0 , mp['U'] = 1 , mp['R'] = 2 , mp['L'] = 3;
while(~scanf(" %d %d",&N,&M)){
memset(dp , Inf , sizeof(dp));
for(int i = 1 ; i <= N ; i++){
for(int j = 1 ; j <= M ; j++){
scanf(" %c",&S[i][j]);
if(S[i][j] == 'R') sx = i , sy = j;
else if(S[i][j] == 'E') ex = i , ey = j;
}
}
scanf(" %s",op);
len = strlen(op);
Bfs();
int ans = Inf;
for(int i = 0 ; i <= len ; i++){
ans = min(ans , dp[i][ex][ey]);
}
printf("%d\n",ans);
}
}