913. Cat and Mouse (图上博弈+ dp )

A game on an undirected graph is played by two players, Mouse and Cat, who alternate turns.

The graph is given as follows: graph[a] is a list of all nodes b such that ab is an edge of the graph.

Mouse starts at node 1 and goes first, Cat starts at node 2 and goes second, and there is a Hole at node 0.

During each player's turn, they must travel along one edge of the graph that meets where they are.  For example, if the Mouse is at node 1, it must travel to any node in graph[1].

Additionally, it is not allowed for the Cat to travel to the Hole (node 0.)

Then, the game can end in 3 ways:

  • If ever the Cat occupies the same node as the Mouse, the Cat wins.
  • If ever the Mouse reaches the Hole, the Mouse wins.
  • If ever a position is repeated (ie. the players are in the same position as a previous turn, and it is the same player's turn to move), the game is a draw.

Given a graph, and assuming both players play optimally, return 1 if the game is won by Mouse, 2 if the game is won by Cat, and 0 if the game is a draw.

Example 1:

Input: [[2,5],[3],[0,4,5],[1,4,5],[2,3],[0,2,3]]
Output: 0
Explanation:
4---3---1
|   |
2---5
 \ /
  0

Note:

  1. 3 <= graph.length <= 50
  2. It is guaranteed that graph[1] is non-empty.
  3. It is guaranteed that graph[2] contains a non-zero element. 

设状态 f(t,x,y)f(t,x,y) 表示 tt 时刻,老鼠位于 xx 且猫位于 yy 时的结果(0,1 或 2)。
如果当前为老鼠行动,那么他可以走到 f(t+1,i,y),i∈graph[x]f(t+1,i,y),i∈graph[x],如果他走到的这些点结果都是 2,则老鼠必输无疑;若其中有一个是 1,则老鼠必获胜;否则结果就是平局。
对于猫来说,以上分析相反。
我们已经知道的状态有,f(t,0,y)=1f(t,0,y)=1,f(t,x,x)=2f(t,x,x)=2,分别代表老鼠获胜和猫获胜。
若游戏进行了 2n2n 个单位时间还没有结束,则可以宣布平局(待证明,以下为直觉想法)。因为每一次移动老鼠都有可能到达一个新的位置,所以它最多只需要 2n2n 步就可能找到出口(因为猫对应也走了 nn 步)。若超过了 2n2n 步,则老鼠必定走了回头路,此时不管猫在哪,走回头路都是向猫 “妥协” 的选择;同理对猫来说,走回头路也是向老鼠 “妥协” 的结果;故最大的 tt 只需要 2n2n 即可。
我们从 solve(0,1,2)solve(0,1,2) 开始记忆化搜索即可。

思路:设定当前为第k步,老鼠在x点,猫在y点,那么若老鼠win则计为1,猫win则计为2,平局计为0

          根据博弈性质,若后面全为必败态,那么当前是必败的,如后面有必胜态,则当前是必胜的。

           因此,可以根据这个性质去深度优先遍历决定当前状态是必胜还是必败。

代码:

#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
    int  dp[200][100][100];
    int catMouseGame(vector<vector<int>>& graph) {
        int n = graph.size();
        memset(dp,-1,sizeof(dp));
        return solve(graph,0,1,2);
    }
    int solve(vector<vector<int>>& graph,int t,int x,int y)
    {
        if(t>=2*graph.size())
        {
            return 0;
        }
        if(x==y)
        {
            return dp[t][x][y]=2;
        }
        if(x==0)
        {
            return dp[t][x][y]=1;
        }
        if(dp[t][x][y]!=-1)
        {
            return dp[t][x][y];
        }
        int who = t%2;
        if(who==0)
        {
            bool f= 1;
            for(int i=0;i<graph[x].size();i++)
            {
                int nxt = solve(graph,t+1,graph[x][i],y);
                if(nxt==1)
                {
                    return dp[t][x][y]=1;
                }
                else if(nxt!=2)
                {
                    f=0;
                }
            }
            if(f)
            {
                return dp[t][x][y]=2;
            }
            else
            {
                return dp[t][x][y]=0;
            }
        }
        else
        {
            bool f=1;
            for(int i=0;i<graph[y].size();i++)
            {
                if(graph[y][i]==0) continue;
                int nxt = solve(graph,t+1,x,graph[y][i]);
                if(nxt==2)
                {
                    return dp[t][x][y]=2;
                }
                else if(nxt!=1)
                {
                    f=0;
                }
            }
            if(f)
            {
                return dp[t][x][y]=1;
            }
            else return dp[t][x][y]=0;
        }
    }
};

猜你喜欢

转载自blog.csdn.net/qq_40774175/article/details/85218503
cat
今日推荐