leetcode:除數博弈

題目來源:力扣

這是我做的第一道動態規劃題目,今天看了一上午算法導論動態規劃那一章,下午準備檢驗一下自己的理解.雖然這道題難度爲簡單級別,但在自己獨立思考下做出來了,感覺美滋滋!

題目描述:

愛麗絲和鮑勃一起玩遊戲,他們輪流行動。愛麗絲先手開局。
最初,黑板上有一個數字 N 。在每個玩家的回合,玩家需要執行以下操作:
選出任一 x,滿足 0 < x < N 且 N % x == 0 。
用 N - x 替換黑板上的數字 N 。
如果玩家無法執行這些操作,就會輸掉遊戲。
只有在愛麗絲在遊戲中取得勝利時才返回 True,否則返回 false。假設兩個玩家都以最佳狀態參與遊戲。
==========================================================
示例 1:
輸入:2
輸出:true
解釋:愛麗絲選擇 1,鮑勃無法進行操作。
示例 2:
輸入:3
輸出:false
解釋:愛麗絲選擇 1,鮑勃也選擇 1,然後愛麗絲無法進行操作。
==========================================================

審題:

由於題目的主要標籤是動態規劃,因此我直接嘗試從動態規劃的角度去思考該問題.
題目中的關鍵信息是最後一句:兩個玩家都以最佳狀態參與遊戲.我們知道,動態規劃算法通常與最優解問題相關.當然要使用動態規劃算法來解決問題,還需要檢查其他必要條件是否滿足,後面一一進行分析.

該問題中,玩家以最佳狀態參與遊戲意味着玩家會在每一步選擇最好的結果,以保證其取得最終勝利.我們使用布爾數組P[]表示存儲玩家在最優狀態下參與遊戲的最優結果.P[i] = true表示若當前黑板上數字爲i,則在兩個玩家都以最佳狀態參與遊戲的情況下,當前玩家會取得勝利.反之,則表示當前玩家最終會失敗.

我們首先分析該問題是否具有最優子結構形式.由於兩個玩家都以最佳狀態參與遊戲,因此該問題天然地即是最優子結構形式.如果當前黑板上數字爲N,假設當前用戶的最優選擇爲x,則如果後續玩家都已最佳狀態參與遊戲,則有:P[N]=!P[Nx]P[N] = !P[N-x],表示如果對手能夠贏得最終勝利,則當前用戶最終將失敗,如果對手最終失敗,則當前用戶將贏得最終勝利.如果當前用戶無法執行有效選擇,則其最終將失敗.

接下來分析該問題的子問題是否具有重疊,假設當前黑板上數字爲N, 則爲了確定最優的選擇,我們需要判斷每一可能的x(其中N%x==0),計算P[N-x].因此,在計算P[N-x1]時,我們需要計算P[K], K<N-x1, 而當計算P[N-x2]時,我們也要計算P[K], K<N-x2.因此子問題存在重疊結構.

在以上分析中,我們如果黑板上有數爲N,則有N個子問題,P[1], P[2], …P[N], 我們可以使用自底向上的動態規劃算法解決該問題.

java算法:

class Solution {
    //假設布爾數組P存儲用戶最優選擇下最終勝利結果.
    //p[i] = true表示如果當前用戶的選擇範圍爲0~i,則在自己與對手均以最佳狀態參與時,她將勝利
    //p[i] = false表示如果當前用戶的選擇範圍爲0~i,則在自己與對手均以最佳狀態參與時,她將失敗
    
    //當N=1時,用戶無法選擇有效值,因此p[1] = false
    //當N=2時,該用戶當前步選擇1,對手最優結果爲p[1] = false,因此該用戶勝利,因此p[2] = true
    //當N=3時,該用戶當前步只能選擇2,對手最優結果爲p[1] = true,因此該用戶失敗,因此p[3] = false
    //當N=4時,該用戶當前步可以選擇1,2,如果選擇1,對手最優結果爲p[3] = false, 如果選擇2,對手最優結果爲p[2] = true,
    //因此他當前步最優選擇爲1,p[4] = true
    

    public boolean divisorGame(int N) {
        boolean[] play = new boolean[N+1];
        play[1] = false;

        for(int i = 2; i <= N; i++){
            for(int j = 1; j < i; j++){
                if(i % j == 0){ //如果可以選擇j
                    if(play[i-j] == false) //如果下一步對手的最優執行結果爲false,則當前步執行結果爲true
                        play[i] = true;            
                }
            }
        }
        return play[N];
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章