1728. 猫和老鼠 II 记忆化搜索 暴力

1728. 猫和老鼠 II 记忆化搜索 暴力

题目大意:

中文题目就自己看吧,但是要注意一下这个题目的数据范围:

  • \(rows == grid.length\)
  • \(cols = grid[i].length\)
  • \(1 <= rows, cols <= 8\)
  • \(grid[i][j]\) 只包含字符 \('C'\)\('M'\)\('F'\)\('.'\)\('\#'\)
  • \(grid\) 中只包含一个 $'C' \(,\)'M'$ 和 $'F' $。
  • \(1 <= catJump, mouseJump <= 8\)

题解:

这种带有博弈性质的题目,如果范围小可以直接暴力搜索,然后可以加一点优化就是记忆化搜索。

定义\(dp[x1][y1][x2][y2][step][now]\) 表示当前老鼠在位置 \((x1,y1)\) ,猫在位置 \((x2,y2)\) ,已经走了 \(step\) 步了,当前的先手是 老鼠now = 0,猫 now = 1。

对于先手来说只要子状态有一个是返回false,那么表示先手必胜。

然后如果使用题目的中1000步来做限制,那么会TLE,然后经过测试发现并不需要这么大,200也是可以过的。

这个题目用到了必胜和必败状态的推导。

必胜必败状态的推导

class Solution {
public:
int dp[10][10][10][10][200][2];
vector<string> Grid;
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
int clen,mlen,rows,cols;
    bool dfs(int sx,int sy,int gx,int gy,int step,int cur){
        int &ans = dp[sx][sy][gx][gy][step][cur];
        if(ans!=-1) return ans;
        if(step>=199) return ans = cur;
        if(cur==0){
            if(!dfs(sx,sy,gx,gy,step+1,1)) return true;
            for(int i=0;i<4;i++){
                for(int j=1;j<=mlen;j++){
                    int tx = sx + dx[i]*j;
                    int ty = sy + dy[i]*j;
                    if(tx<0||ty<0||tx>=rows||ty>=cols) break;
                    if(Grid[tx][ty]=='#') break;
                    if(Grid[tx][ty]=='F') return ans = true;
                    if(tx==gx&&ty==gy) continue;
                    if(!dfs(tx,ty,gx,gy,step+1,1)) return ans = true;
                }
            }
            return ans = false;
        }
        else{
            if(!dfs(sx,sy,gx,gy,step+1,0)) return true;
            for(int i=0;i<4;i++){
                for(int j=1;j<=clen;j++){
                int tx = gx + dx[i]*j;
                int ty = gy + dy[i]*j;
                if(tx<0||ty<0||tx>=rows||ty>=cols) break;
                    if(Grid[tx][ty]=='#') break;
                    if(Grid[tx][ty]=='F') return ans = true;
                    if(tx==sx&&ty==sy) return ans = true;
                    if(!dfs(sx,sy,tx,ty,step+1,0)) return ans = true;
                }
            }
            return ans = false;
        }
    }
    bool canMouseWin(vector<string>& grid, int catJump, int mouseJump) {
        Grid = grid;
        clen = catJump,mlen = mouseJump;
        rows = grid.size(),cols = grid[0].length();
        int sx,sy,gx,gy;
        for(int i=0;i<rows;i++){
            for(int j=0;j<cols;j++){
                if(grid[i][j]=='M') sx = i,sy = j;
                if(grid[i][j]=='C') gx = i,gy = j;
            }
        }
        memset(dp,-1,sizeof(dp));
        bool flag = dfs(sx,sy,gx,gy,0,0);
        bool ans;
        if(flag) ans = true;
        else ans = false;
        return ans;
    }
};
posted @ 2021-01-24 19:00  EchoZQN  阅读(95)  评论(0编辑  收藏  举报