CF1065D

如果不喜欢过长代码的看官,请移步其他题解...

这题其实思想极其简单:

棋盘问题常见的算法都比较暴力,常用的有搜索和状压dp

而这道题显然没啥能状压的,所以我们考虑搜索

但是仅仅搜索是不够的,因为有极大的可能搜到死...

所以我们引入记忆化

设状态f[i][j][k][0/1/2]代表目前在点(i,j)处,上一个到达的点(注意是达成要求而非经过)的编号为k,目前的棋子种类为1/2/3时,所需要的最小代价

当然这还不够,我们还要保证在代价最小时更换棋子次数最小,所以我们再用状态g[i][j][k][0/1/2]更新,下标含义与上述相同,表示对应状态所需的最小棋子更换次数

注意优先更新f,在保证f合法的情况下维护g

然后用bfs更新即可

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <vector>
#include <ctime>
#include <set>
#include <deque>
#include <bitset>
using namespace std;
int dp[15][15][105][3];
int g[15][15][105][3];
int xp[105],yp[105];
int maps[15][15];
int dir[8][2]={{1,2},{2,1},{2,-1},{-1,2},{-1,-2},{-2,-1},{1,-2},{-2,1}};
int n;
bool check(int x,int y)
{
    if(x>0&&x<=n&&y>0&&y<=n)
    {
        return 1;
    }
    return 0;
}
void bfs()
{
    memset(dp,0x3f,sizeof(dp));
    memset(g,0x3f,sizeof(g));
    dp[xp[1]][yp[1]][1][0]=0;//
    dp[xp[1]][yp[1]][1][1]=0;//
    dp[xp[1]][yp[1]][1][2]=0;//
    g[xp[1]][yp[1]][1][0]=0;
    g[xp[1]][yp[1]][1][1]=0;
    g[xp[1]][yp[1]][1][2]=0;
    queue <int> Qx,Qy,Qz,Qv;
    for(int i=0;i<=2;i++)
    {
        Qx.push(xp[1]);
        Qy.push(yp[1]);
        Qz.push(i);
        Qv.push(1);
    }
    while(!Qx.empty())
    {
        int ux=Qx.front();
        int uy=Qy.front();
        int uz=Qz.front();
        int uv=Qv.front();
        Qx.pop();
        Qy.pop();
        Qz.pop();
        Qv.pop();
        if(uv==n*n)
        {
            continue;
        }
        if(uz==0)
        {
            for(int i=1;i<=n;i++)
            {
                if(i==uy)
                {
                    continue;
                }
                if(maps[ux][i]==uv+1)
                {
                    if(dp[ux][i][uv+1][uz]>dp[ux][uy][uv][uz]+1)
                    {
                        dp[ux][i][uv+1][uz]=dp[ux][uy][uv][uz]+1;
                        g[ux][i][uv+1][uz]=g[ux][uy][uv][uz];
                        Qx.push(ux);
                        Qy.push(i);
                        Qz.push(uz);
                        Qv.push(uv+1);
                    }else if(dp[ux][i][uv+1][uz]==dp[ux][uy][uv][uz]+1&&g[ux][i][uv+1][uz]>g[ux][uy][uv][uz])
                    {
                        g[ux][i][uv+1][uz]=g[ux][uy][uv][uz];
                        Qx.push(ux);
                        Qy.push(i);
                        Qz.push(uz);
                        Qv.push(uv+1);
                    }
                }else
                {
                    if(dp[ux][i][uv][uz]>dp[ux][uy][uv][uz]+1)
                    {
                        dp[ux][i][uv][uz]=dp[ux][uy][uv][uz]+1;
                        g[ux][i][uv][uz]=g[ux][uy][uv][uz];
                        Qx.push(ux);
                        Qy.push(i);
                        Qz.push(uz);
                        Qv.push(uv);
                    }else if(dp[ux][i][uv][uz]==dp[ux][uy][uv][uz]+1&&g[ux][i][uv][uz]>g[ux][uy][uv][uz])
                    {
                        g[ux][i][uv][uz]=g[ux][uy][uv][uz];
                        Qx.push(ux);
                        Qy.push(i);
                        Qz.push(uz);
                        Qv.push(uv);
                    }
                }
            }
            for(int i=1;i<=n;i++)
            {
                if(i==ux)
                {
                    continue;
                }
                if(maps[i][uy]==uv+1)
                {
                    if(dp[i][uy][uv+1][uz]>dp[ux][uy][uv][uz]+1)
                    {
                        dp[i][uy][uv+1][uz]=dp[ux][uy][uv][uz]+1;
                        g[i][uy][uv+1][uz]=g[ux][uy][uv][uz];
                        Qx.push(i);
                        Qy.push(uy);
                        Qz.push(uz);
                        Qv.push(uv+1);
                    }else if(dp[i][uy][uv+1][uz]==dp[ux][uy][uv][uz]+1&&g[i][uy][uv+1][uz]>g[ux][uy][uv][uz])
                    {
                        g[i][uy][uv+1][uz]=g[ux][uy][uv][uz];
                        Qx.push(i);
                        Qy.push(uy);
                        Qz.push(uz);
                        Qv.push(uv+1);
                    }
                }else
                {
                    if(dp[i][uy][uv][uz]>dp[ux][uy][uv][uz]+1)
                    {
                        dp[i][uy][uv][uz]=dp[ux][uy][uv][uz]+1;
                        g[i][uy][uv][uz]=g[ux][uy][uv][uz];
                        Qx.push(i);
                        Qy.push(uy);
                        Qz.push(uz);
                        Qv.push(uv);
                    }else if(dp[i][uy][uv][uz]==dp[ux][uy][uv][uz]+1&&g[i][uy][uv][uz]>g[ux][uy][uv][uz])
                    {
                        g[i][uy][uv][uz]=g[ux][uy][uv][uz];
                        Qx.push(i);
                        Qy.push(uy);
                        Qz.push(uz);
                        Qv.push(uv);
                    }
                }
            }
            if(dp[ux][uy][uv][1]>dp[ux][uy][uv][uz]+1)
            {
                dp[ux][uy][uv][1]=dp[ux][uy][uv][uz]+1;
                g[ux][uy][uv][1]=g[ux][uy][uv][uz]+1;
                Qx.push(ux);
                Qy.push(uy);
                Qz.push(1);
                Qv.push(uv);
            }else if(dp[ux][uy][uv][1]==dp[ux][uy][uv][uz]+1&&g[ux][uy][uv][1]>g[ux][uy][uv][uz]+1)
            {
                g[ux][uy][uv][1]=g[ux][uy][uv][uz]+1;
                Qx.push(ux);
                Qy.push(uy);
                Qz.push(1);
                Qv.push(uv);
            }
            if(dp[ux][uy][uv][2]>dp[ux][uy][uv][uz]+1)
            {
                dp[ux][uy][uv][2]=dp[ux][uy][uv][uz]+1;
                g[ux][uy][uv][2]=g[ux][uy][uv][uz]+1;
                Qx.push(ux);
                Qy.push(uy);
                Qz.push(2);
                Qv.push(uv);
            }else if(dp[ux][uy][uv][2]==dp[ux][uy][uv][uz]+1&&g[ux][uy][uv][2]>g[ux][uy][uv][uz]+1)
            {
                g[ux][uy][uv][2]=g[ux][uy][uv][uz]+1;
                Qx.push(ux);
                Qy.push(uy);
                Qz.push(2);
                Qv.push(uv);
            }
        }else if(uz==1)//
        {
            for(int i=0;i<8;i++)
            {
                int tx=ux+dir[i][0];
                int ty=uy+dir[i][1];
                if(tx<=0||tx>n||ty<=0||ty>n)
                {
                    continue;
                }
                if(maps[tx][ty]==uv+1)
                {
                    if(dp[tx][ty][uv+1][1]>dp[ux][uy][uv][1]+1)
                    {
                        dp[tx][ty][uv+1][1]=dp[ux][uy][uv][1]+1;
                        g[tx][ty][uv+1][1]=g[ux][uy][uv][1];
                        Qx.push(tx);
                        Qy.push(ty);
                        Qv.push(uv+1);
                        Qz.push(1);
                    }else if(dp[tx][ty][uv+1][uz]==dp[ux][uy][uv][uz]+1&&g[tx][ty][uv+1][uz]>g[ux][uy][uv][uz])
                    {
                        g[tx][ty][uv+1][uz]=g[ux][uy][uv][uz];
                        Qx.push(tx);
                        Qy.push(ty);
                        Qz.push(uz);
                        Qv.push(uv+1);
                    } 
                }else
                {
                    if(dp[tx][ty][uv][1]>dp[ux][uy][uv][1]+1)
                    {
                        dp[tx][ty][uv][1]=dp[ux][uy][uv][1]+1;
                        g[tx][ty][uv][1]=g[ux][uy][uv][1];
                        Qx.push(tx);
                        Qy.push(ty);
                        Qv.push(uv);
                        Qz.push(1);
                    }else if(dp[tx][ty][uv][uz]==dp[ux][uy][uv][uz]+1&&g[tx][ty][uv][uz]>g[ux][uy][uv][uz])
                    {
                        g[tx][ty][uv][uz]=g[ux][uy][uv][uz];
                        Qx.push(tx);
                        Qy.push(ty);
                        Qz.push(uz);
                        Qv.push(uv);
                    } 
                }
            }
            if(dp[ux][uy][uv][0]>dp[ux][uy][uv][uz]+1)
            {
                dp[ux][uy][uv][0]=dp[ux][uy][uv][uz]+1;
                g[ux][uy][uv][0]=g[ux][uy][uv][uz]+1;
                Qx.push(ux);
                Qy.push(uy);
                Qz.push(0);
                Qv.push(uv);
            }else if(dp[ux][uy][uv][0]==dp[ux][uy][uv][uz]+1&&g[ux][uy][uv][0]>g[ux][uy][uv][uz]+1)
            {
                g[ux][uy][uv][0]=g[ux][uy][uv][uz]+1;
                Qx.push(ux);
                Qy.push(uy);
                Qz.push(0);
                Qv.push(uv);
            }
            if(dp[ux][uy][uv][2]>dp[ux][uy][uv][uz]+1)
            {
                dp[ux][uy][uv][2]=dp[ux][uy][uv][uz]+1;
                g[ux][uy][uv][2]=g[ux][uy][uv][uz]+1;
                Qx.push(ux);
                Qy.push(uy);
                Qz.push(2);
                Qv.push(uv);
            }else if(dp[ux][uy][uv][2]==dp[ux][uy][uv][uz]+1&&g[ux][uy][uv][2]>g[ux][uy][uv][uz]+1)
            {
                g[ux][uy][uv][2]=g[ux][uy][uv][uz]+1;
                Qx.push(ux);
                Qy.push(uy);
                Qz.push(2);
                Qv.push(uv);
            }
        }else if(uz==2)
        {
            for(int i=1;i<=n;i++)
            {
                int tx=ux+i;
                int ty=uy+i;
                if(check(tx,ty))
                {
                    if(maps[tx][ty]==uv+1)
                    {
                        if(dp[tx][ty][uv+1][2]>dp[ux][uy][uv][2]+1)
                        {
                            dp[tx][ty][uv+1][2]=dp[ux][uy][uv][2]+1;
                            g[tx][ty][uv+1][2]=g[ux][uy][uv][2];
                            Qx.push(tx);
                            Qy.push(ty);
                            Qv.push(uv+1);
                            Qz.push(2);
                        }else if(dp[tx][ty][uv+1][uz]==dp[ux][uy][uv][uz]+1&&g[tx][ty][uv+1][uz]>g[ux][uy][uv][uz])
                        {
                            g[tx][ty][uv+1][uz]=g[ux][uy][uv][uz];
                            Qx.push(tx);
                            Qy.push(ty);
                            Qz.push(uz);
                            Qv.push(uv+1);
                        } 
                    }else
                    {
                        if(dp[tx][ty][uv][2]>dp[ux][uy][uv][2]+1)
                        {
                            dp[tx][ty][uv][2]=dp[ux][uy][uv][2]+1;
                            g[tx][ty][uv][2]=g[ux][uy][uv][2];
                            Qx.push(tx);
                            Qy.push(ty);
                            Qv.push(uv);
                            Qz.push(2);
                        }else if(dp[tx][ty][uv][uz]==dp[ux][uy][uv][uz]+1&&g[tx][ty][uv][uz]>g[ux][uy][uv][uz])
                        {
                            g[tx][ty][uv+1][uz]=g[ux][uy][uv][uz];
                            Qx.push(tx);
                            Qy.push(ty);
                            Qz.push(uz);
                            Qv.push(uv+1);
                        } 
                    }
                }
                tx=ux+i;
                ty=uy-i;
                if(check(tx,ty))
                {
                    if(maps[tx][ty]==uv+1)
                    {
                        if(dp[tx][ty][uv+1][2]>dp[ux][uy][uv][2]+1)
                        {
                            dp[tx][ty][uv+1][2]=dp[ux][uy][uv][2]+1;
                            g[tx][ty][uv+1][2]=g[ux][uy][uv][2];
                            Qx.push(tx);
                            Qy.push(ty);
                            Qv.push(uv+1);
                            Qz.push(2);
                        }else if(dp[tx][ty][uv+1][uz]==dp[ux][uy][uv][uz]+1&&g[tx][ty][uv+1][uz]>g[ux][uy][uv][uz])
                        {
                            g[tx][ty][uv+1][uz]=g[ux][uy][uv][uz];
                            Qx.push(tx);
                            Qy.push(ty);
                            Qz.push(uz);
                            Qv.push(uv+1);
                        } 
                    }else
                    {
                        if(dp[tx][ty][uv][2]>dp[ux][uy][uv][2]+1)
                        {
                            dp[tx][ty][uv][2]=dp[ux][uy][uv][2]+1;
                            g[tx][ty][uv][2]=g[ux][uy][uv][2];
                            Qx.push(tx);
                            Qy.push(ty);
                            Qv.push(uv);
                            Qz.push(2);
                        }else if(dp[tx][ty][uv][uz]==dp[ux][uy][uv][uz]+1&&g[tx][ty][uv][uz]>g[ux][uy][uv][uz])
                        {
                            g[tx][ty][uv][uz]=g[ux][uy][uv][uz];
                            Qx.push(tx);
                            Qy.push(ty);
                            Qz.push(uz);
                            Qv.push(uv);
                        } 
                    }
                }
                tx=ux-i;
                ty=uy+i;
                if(check(tx,ty))
                {
                    if(maps[tx][ty]==uv+1)
                    {
                        if(dp[tx][ty][uv+1][2]>dp[ux][uy][uv][2]+1)
                        {
                            dp[tx][ty][uv+1][2]=dp[ux][uy][uv][2]+1;
                            g[tx][ty][uv+1][2]=g[ux][uy][uv][2];
                            Qx.push(tx);
                            Qy.push(ty);
                            Qv.push(uv+1);
                            Qz.push(2);
                        }else if(dp[tx][ty][uv+1][uz]==dp[ux][uy][uv][uz]+1&&g[tx][ty][uv+1][uz]>g[ux][uy][uv][uz])
                        {
                            g[tx][ty][uv+1][uz]=g[ux][uy][uv][uz];
                            Qx.push(tx);
                            Qy.push(ty);
                            Qz.push(uz);
                            Qv.push(uv+1);
                        } 
                    }else
                    {
                        if(dp[tx][ty][uv][2]>dp[ux][uy][uv][2]+1)
                        {
                            dp[tx][ty][uv][2]=dp[ux][uy][uv][2]+1;
                            g[tx][ty][uv][2]=g[ux][uy][uv][2];
                            Qx.push(tx);
                            Qy.push(ty);
                            Qv.push(uv);
                            Qz.push(2);
                        }else if(dp[tx][ty][uv][uz]==dp[ux][uy][uv][uz]+1&&g[tx][ty][uv][uz]>g[ux][uy][uv][uz])
                        {
                            g[tx][ty][uv][uz]=g[ux][uy][uv][uz];
                            Qx.push(tx);
                            Qy.push(ty);
                            Qz.push(uz);
                            Qv.push(uv);
                        } 
                    }
                }
                tx=ux-i;
                ty=uy-i;
                if(check(tx,ty))
                {
                    if(maps[tx][ty]==uv+1)
                    {
                        if(dp[tx][ty][uv+1][2]>dp[ux][uy][uv][2]+1)
                        {
                            dp[tx][ty][uv+1][2]=dp[ux][uy][uv][2]+1;
                            g[tx][ty][uv+1][2]=g[ux][uy][uv][2];
                            Qx.push(tx);
                            Qy.push(ty);
                            Qv.push(uv+1);
                            Qz.push(2);
                        }else if(dp[tx][ty][uv+1][uz]==dp[ux][uy][uv][uz]+1&&g[tx][ty][uv+1][uz]>g[ux][uy][uv][uz])
                        {
                            g[tx][ty][uv+1][uz]=g[ux][uy][uv][uz];
                            Qx.push(tx);
                            Qy.push(ty);
                            Qz.push(uz);
                            Qv.push(uv+1);
                        }  
                    }else
                    {
                        if(dp[tx][ty][uv][2]>dp[ux][uy][uv][2]+1)
                        {
                            dp[tx][ty][uv][2]=dp[ux][uy][uv][2]+1;
                            g[tx][ty][uv][2]=g[ux][uy][uv][2];
                            Qx.push(tx);
                            Qy.push(ty);
                            Qv.push(uv);
                            Qz.push(2);
                        }else if(dp[tx][ty][uv][uz]==dp[ux][uy][uv][uz]+1&&g[tx][ty][uv][uz]>g[ux][uy][uv][uz])
                        {
                            g[tx][ty][uv][uz]=g[ux][uy][uv][uz];
                            Qx.push(tx);
                            Qy.push(ty);
                            Qz.push(uz);
                            Qv.push(uv);
                        } 
                    }
                }
            }
            if(dp[ux][uy][uv][0]>dp[ux][uy][uv][uz]+1)
            {
                dp[ux][uy][uv][0]=dp[ux][uy][uv][uz]+1;
                g[ux][uy][uv][0]=g[ux][uy][uv][uz]+1;
                Qx.push(ux);
                Qy.push(uy);
                Qz.push(0);
                Qv.push(uv);
            }else if(dp[ux][uy][uv][1]>dp[ux][uy][uv][uz]+1&&g[ux][uy][uv][0]>g[ux][uy][uv][uz]+1)
            {
                g[ux][uy][uv][0]=g[ux][uy][uv][uz]+1;
                Qx.push(ux);
                Qy.push(uy);
                Qz.push(0);
                Qv.push(uv);
            }
            if(dp[ux][uy][uv][1]>dp[ux][uy][uv][uz]+1)
            {
                dp[ux][uy][uv][1]=dp[ux][uy][uv][uz]+1;
                g[ux][uy][uv][1]=g[ux][uy][uv][uz]+1;
                Qx.push(ux);
                Qy.push(uy);
                Qz.push(1);
                Qv.push(uv);
            }else if(dp[ux][uy][uv][1]==dp[ux][uy][uv][uz]+1&&g[ux][uy][uv][1]>g[ux][uy][uv][uz]+1)
            {
                g[ux][uy][uv][1]=g[ux][uy][uv][uz]+1;
                Qx.push(ux);
                Qy.push(uy);
                Qz.push(1);
                Qv.push(uv);
            }
        }
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            scanf("%d",&maps[i][j]);
            xp[maps[i][j]]=i;
            yp[maps[i][j]]=j;
        }
    }
    bfs();
    int ans=0x3f3f3f3f;
    int ret=0x3f3f3f3f;
    for(int i=0;i<=2;i++)
    {
        if(ans>dp[xp[n*n]][yp[n*n]][n*n][i])
        {
            ans=dp[xp[n*n]][yp[n*n]][n*n][i];
            ret=g[xp[n*n]][yp[n*n]][n*n][i];
        }else if(ret>g[xp[n*n]][yp[n*n]][n*n][i]&&ans==dp[xp[n*n]][yp[n*n]][n*n][i])
        {
            ret=g[xp[n*n]][yp[n*n]][n*n][i];
        }
    }
    printf("%d %d\n",ans,ret);
    return 0;
}

 

posted @ 2018-10-30 20:37  lleozhang  Views(223)  Comments(0Edit  收藏  举报
levels of contents