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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值