Leetcode 486. Predict the Winner

題目大意:有一個非負的整數序列,長度爲n,現在有兩個玩家,他們每次可以從該序列的頭(或尾)拿走一個數,直到該序列被拿完。最後哪個玩家手裏的數加起來的和最大,那麼他贏。現給定一個序列,求判斷第一個玩家(即先手)是否能贏。


分析思路:由於每個玩家都是會在“當前的情況下”取最優的解,也就是最大的數,那麼,實際上,這就是一個遞歸問題。即,玩家A到底是取該整數序列頭的那個數還是尾的那個數,是要考慮到下一步,玩家B取的是哪個數。也就是說,玩家A要取的數(設當前情況下,序列的頭和尾對應的數,分別是head_num, tail_num),應該與下一步玩家B要取的數(設爲n)的差值最大(即,max(head_num, tail_num))。玩家B要取數時,他也是這麼考慮的。於是,解題代碼如下:

class Solution{
public:
    bool PredictTheWinner(vector<int>& nums){
        int len = nums.size();
        if(1 == len) return true;
        return helper(nums, 0, len - 1) >= 0;
    }
    int helper(vector<int>& nums, int start, int end){
        if(start == end) return nums[start];
        int a = nums[start] - helper(nums, start + 1, end);
        int b = nums[end] - helper(nums, start, end - 1);
        return max(a, b);
    }
};
上面,只解決了,判斷第一個玩家能夠贏。如果,要求出第一個或第二個玩家,能拿到的所有的數的總和最大,又該如何做呢?其實,用另外一個數組記錄即可,這裏假設要求出第一個玩家A的最後的所有數的總和,那麼可用一個二維數組dp[start][end]來記錄,當前玩家A在數組區間[start, end]中,所取到的數的總和,比第二個玩家B在該區間取到的數的總和,要多出的分數。由此,dp[0][len-1]表示的就是玩家A在整個數組區間[0, len - 1]所取得的總分數(設爲x),比玩家B所取得總分數(設爲y)所多的分數(設爲k)。另外,設該數組區間的總和爲w,則此時有方程組:x-y=k;x+y=w。解方程得:x=(w+k)/2;y=(w-k)/2。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章