dp+bfs Buggy Robot

题目链接:https://nanti.jisuanke.com/t/40891

题意:

给你一个地图,机器人从起点到终点按照字符串的指示前进,如果遇到障碍或者出边界就停留在原地,不算违规。

问你最少修改字符串的几个字符,才能让机器人到终点。

分析:

用dp[i][j][k]表示扫描完前k个字符之后,到达地图坐标(i,j)上的最小代价。

把每个状态都依次穷举,加入队列后bfs。

#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
const int maxn=1e5+10;
char s[60][60],pre[60];
int dp[60][60][60];
int h,w;
struct node{
    int x,y,pos;
    node(int x,int y,int pos):x(x),y(y),pos(pos){}
};
queue<node> q;
bool check(int x,int y){
    return x>0&&x<=h&&y>0&&y<=w&&s[x][y]!='#';
}
int main(){
    scanf("%d%d",&h,&w);
    int sx,sy,gx,gy;
    for(int i=1;i<=h;i++){
        scanf("%s",s[i]+1);
        for(int j=1;j<=w;j++){
            if(s[i][j]=='S') sx=i,sy=j;
            if(s[i][j]=='G') gx=i,gy=j;
        }
    }
    scanf("%s",pre+1);
    int len=strlen(pre+1);
    int nxt[4][2]={{0,1},{0,-1},{-1,0},{1,0}}; 
    int m['Z'+1];
    m['R']=0;m['L']=1;m['U']=2;m['D']=3;
    meminf(dp);
    dp[sx][sy][0]=0;
    q.push(node(sx,sy,0));
    while(!q.empty()){
        node now=q.front();q.pop();
        for(int i=0;i<4;i++){
            //在pos位置处添加一个指令 
            int nowx=now.x+nxt[i][0],nowy=now.y+nxt[i][1];
            if(check(nowx,nowy))
            if(dp[nowx][nowy][now.pos]>dp[now.x][now.y][now.pos]+1){
                dp[nowx][nowy][now.pos]=dp[now.x][now.y][now.pos]+1;
                q.push(node(nowx,nowy,now.pos));
            }
        }
        if(now.pos<len){
            //在pos位置处删除一个指令 
            if(dp[now.x][now.y][now.pos+1]>dp[now.x][now.y][now.pos]+1){
                dp[now.x][now.y][now.pos+1]=dp[now.x][now.y][now.pos]+1;
                q.push(node(now.x,now.y,now.pos+1));
            }
            //按照初始指令来行进 
            int pos=now.pos+1;//扫描下一个 
            int nowx=now.x+nxt[m[pre[pos]]][0],nowy=now.y+nxt[m[pre[pos]]][1];
        //    cout<<" "<<nowx<<" "<<nowy<<endl;
            if(!check(nowx,nowy)) nowx=now.x,nowy=now.y;
            if(dp[nowx][nowy][now.pos+1]>dp[now.x][now.y][now.pos]){
                //前者可以由后者自然转换来,如果后者代价更低是可以直接变更的
                 dp[nowx][nowy][now.pos+1]=dp[now.x][now.y][now.pos];
                 q.push(node(nowx,nowy,now.pos+1));
            } 
        }
    }
    int ans=inf;
    for(int i=0;i<=len;i++) ans=min(ans,dp[gx][gy][i]);
    cout<<ans<<endl;
    return 0;
}

 

转载于:https://www.cnblogs.com/qingjiuling/p/11356696.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值