Luogu P3956 棋盘(dfs)

#include<cstdio>
#include<cstring>
using namespace std;

inline int min(int x,int y){return x<y?x:y;}

int m,n,ans=0x7ffffff,vis[105][105],c[105][105],minn[105][105][5];

int dx[5]={0,1,0,-1,0},dy[5]={0,0,1,0,-1};
inline void read(int &x){
    int ans=0,f=1;
    char c=getchar();
    while(c>'9'||c<'0'){
        if(c=='-')f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        ans=ans*10+int(c)-48;
        c=getchar();
    }
    x=ans*f;
}

inline void readln(int &x){
    read(x);
    putchar('\n');
}

inline void write(int x){
    if(x<0)x=-x,putchar('-');
    if(x>9)write(x/10);
    putchar(x%10+48);
}

inline void writeln(int x){
    write(x);
    putchar('\n');
}

inline void dfs(int money,int x,int y,int now,int magic){
    if(money>=minn[x][y][magic])return;//记忆化,好东西,
    else minn[x][y][magic]=money;//最后一个点减少1min的好法宝
    if(x==m&&y==m){
        ans=min(ans,money);
        return;
    }
    if(money>=ans)return;
    for(int i=1;i<=4;i++){
        int ux=x+dx[i],uy=y+dy[i];
        if(ux>m||ux<1||uy>m||uy<1||vis[ux][uy])continue;
        int nowc=c[x][y],nextc=c[ux][uy];
        if(!nextc){
            if(nowc){
                vis[ux][uy]=1;
                dfs(money+2,ux,uy,now+1,c[x][y]);
                vis[ux][uy]=0;
            }
        }
        else{
            if(nowc==nextc||(nowc==0&&magic==nextc)){//注意无色变有色(nowc==0&&magic==nextc)
                vis[ux][uy]=1;
                dfs(money,ux,uy,now+1,0);
                vis[ux][uy]=0;
            }
            else {
                vis[ux][uy]=1;
                dfs(money+1,ux,uy,now+1,0);
                vis[ux][uy]=0;
            }
        }
    }
}

int main(){
    memset(minn,0x3f,sizeof(minn));
    read(m);read(n);
    for(int i=1;i<=n;i++){
        int x,y,s;
        read(x);read(y);read(s);
        c[x][y]=s+1;
    }
    dfs(0,1,1,1,0);
    if(ans==0x7ffffff)writeln(-1);
    else writeln(ans);
}

猜你喜欢

转载自www.cnblogs.com/Y15BeTa/p/10348677.html
今日推荐