Leetcode 913. 貓和老鼠 【dp】【dfs剪枝】

兩個玩家分別扮演貓(Cat)和老鼠(Mouse)在無向圖上進行遊戲,他們輪流行動。

該圖按下述規則給出:graph[a] 是所有結點 b 的列表,使得 ab 是圖的一條邊。

老鼠從結點 1 開始並率先出發,貓從結點 2 開始且隨後出發,在結點 0 處有一個洞。

在每個玩家的回合中,他們必須沿着與他們所在位置相吻合的圖的一條邊移動。例如,如果老鼠位於結點 1,那麼它只能移動到 graph[1] 中的(任何)結點去。

此外,貓無法移動到洞(結點 0)裏。

然後,遊戲在出現以下三種情形之一時結束:

如果貓和老鼠佔據相同的結點,貓獲勝。
如果老鼠躲入洞裏,老鼠獲勝。
如果某一位置重複出現(即,玩家們的位置和移動順序都與上一個回合相同),遊戲平局。
給定 graph,並假設兩個玩家都以最佳狀態參與遊戲,如果老鼠獲勝,則返回 1;如果貓獲勝,則返回 2;如果平局,則返回 0。

 

示例:

輸入:[[2,5],[3],[0,4,5],[1,4,5],[2,3],[0,2,3]]
輸出:0
解釋:
4---3---1
|   |
2---5
 \ /
  0
 

提示:

3 <= graph.length <= 200
保證 graph[1] 非空。
保證 graph[2] 包含非零元素。

 

設圖中節點數爲n

dp數組dp[c][m][d]c爲cat的位置,m是mouse的位置,d是當前已經走的步數

判斷是夠會平局就是判斷是否會出現重複的路線,當每個人都走n步,共計2n步時一定會出現重複路線,即可返回0(平局)

當c==m的時候老鼠和貓在同一位置,返回2,貓勝,當m==0時老鼠回到洞裏,返回1,老鼠勝

但要注意c不能等於0

dfs實現中通過當前d的奇偶判斷到誰的回合,在貓的回合中假設貓會選擇最優解,所以所有下一可行節點中只要有一個是可以返回2的,就直接返回dp[c][m][d]=2,若沒有一定獲勝的可能性,也不能直接判斷當前dp[c][m][d]是等於0還是等於1,因爲貓會選擇最優解,所以除非所有可行節點全部返回1(老鼠勝),否則一定會反會0

老鼠的回合同理

具體實現看代碼

class Solution {
public:
    int catMouseGame(vector<vector<int>>& graph) {
        int n = graph.size();
        vector<vector<vector<int>>> dp(n, vector<vector<int>>(n, vector<int>(n * 2, -1)));
        return dfs(2, 1, 0, graph, dp);
    }
    int dfs(int c, int m, int d, vector<vector<int>>& v, vector<vector<vector<int>>>& dp) {
        if(d == 2 * v.size()) return 0;
        if(c == m) return dp[c][m][d] = 2;
        if(m == 0) return dp[c][m][d] = 1;
        if(dp[c][m][d] != -1) return dp[c][m][d];
        if(d & 1) {
            bool mw = 1;
            for(int i = 0; i < v[c].size(); i++) {
                if(v[c][i] == 0) continue;
                int next = dfs(v[c][i], m, d + 1, v, dp);
                if(next == 2) return dp[c][m][d] = 2;
                else if(next != 1) mw = 0;
            }
            if(mw) return dp[c][m][d] = 1;
            else return dp[c][m][d] = 0;
        } else {
            bool cw = 1;
            for(int i = 0; i < v[m].size(); i++) {
                int next = dfs(c, v[m][i], d + 1, v, dp);
                if(next == 1) return dp[c][m][d] = 1;
                else if(next != 2) cw = 0;
            }
            if(cw) return dp[c][m][d] = 2;
            else return dp[c][m][d] = 0;
        }
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章