1. 程式人生 > >913. Cat and Mouse (圖上博弈+ dp )

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;
        }
    }
};