【题意】求悟空到师傅的最短距离,这中途会有一些门,悟空必须依次拿到钥匙,打开所有的门,中途遇到妖怪就会多停留1s,求悟空救出师傅的最短时间!

【解题思路】我的第一道dfs+状压!其中dp[x][y][k][s]中,x,y代表位置,k代表拿到了k把钥匙,s代表状态。

【AC代码】

#include <stdio.h>
#include <queue>
#include <string.h>
#include <assert.h>
#include <iostream>
using namespace std;
const int maxn = 102;
const int inf = 0x3f3f3f3f;
struct node{
   int x,y,k,s,d;
   node(){}
   node(int x,int y,int k,int s,int d):x(x),y(y),k(k),s(s),d(d){}
};
int dir[4][2]={{0,1},{0,-1},{-1,0},{1,0}};
int dp[maxn][maxn][10][32];
char maze[maxn][maxn];
int n,m,sx,sy,cnt;
int bfs(int sx,int sy)
{
    queue<node>que;
    int ans = inf;
    que.push(node(sx,sy,0,0,0));
    while(!que.empty())
    {
        node cur = que.front();
        que.pop();
        int x=cur.x,y=cur.y,k=cur.k,s=cur.s;
        if(k==m&&maze[x][y]=='T')
        {
            ans = min(ans,cur.d);
        }
        if(dp[x][y][k][s]!=-1)continue;
        dp[x][y][k][s]=cur.d;
        for(int i=0;i<4;i++)
        {
            int dx=x+dir[i][0];
            int dy=y+dir[i][1];
            int st = maze[dx][dy]-'A';
            if(st>=0&&st<cnt)//杀蛇
            {
                if(s&(1<<st)) que.push(node(dx,dy,k,s,cur.d+1));
                else          que.push(node(dx,dy,k,s^(1<<st),cur.d+2));
            }
            else//拿钥匙
            {
                if(maze[dx][dy]=='1'+k)
                {
                    que.push(node(dx,dy,k+1,s,cur.d+1));
                }
                else if((maze[dx][dy]>='1'&&maze[dx][dy]<'1'+m)||(maze[dx][dy]=='.'||maze[dx][dy]=='K'||maze[dx][dy]=='T'))
                {
                    que.push(node(dx,dy,k,s,cur.d+1));
                }
            }
        }
    }
    return ans;
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        cnt = 0;
        if(n==0&&m==0)return 0;
        memset(dp,-1,sizeof(dp));
        memset(maze,0,sizeof(maze));
        for(int i=1; i<=n; i++)
        {
            scanf("%s",maze[i]+1);
            for(int j=1; j<=n; j++)
            {
                if(maze[i][j]=='S')
                {
                    maze[i][j] = 'A'+cnt;
                    cnt++;
                }
                if(maze[i][j]=='K')
                {
                    sx=i,sy=j;
                }
            }
        }
//        for(int i=1; i<=n; i++)
//        {
//            for(int j=1; j<=n; j++)
//            {
//                printf("%c",maze[i][j]);
//            }
//            printf("\n");
//        }
        int ans = bfs(sx,sy);
        if(ans==inf)
        {
            puts("impossible");
        }
        else
        {
            printf("%d\n",ans);
        }
    }
    return 0;
}