Leetcode 486. Predict the Winner

来源:互联网 发布:mac系统word画流程图 编辑:程序博客网 时间:2024/05/29 16:33

题目大意:有一个非负的整数序列,长度为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。

原创粉丝点击