486. Predict the Winner

来源:互联网 发布:矢量图标库 知乎 编辑:程序博客网 时间:2024/06/08 18:24

越往后做AC率就开始下降了呵呵。不过下降也说明了自己的不足,也说明自己在成长。这道题目是一道比较典型的dp问题,后面一些中等难度的题目很多都是dp问题,dp问题的关键在于问题的分解和最优解公式。

题目描述

Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from either end of the array followed by the player 2 and then player 1 and so on. Each time a player picks a number, that number will not be available for the next player. This continues until all the scores have been chosen. The player with the maximum score wins.

Given an array of scores, predict whether player 1 is the winner. You can assume each player plays to maximize his score.

Example 1:
Input: [1, 5, 2]
Output: False
Explanation: Initially, player 1 can choose between 1 and 2.
If he chooses 2 (or 1), then player 2 can choose from 1 (or 2) and 5. If player 2 chooses 5, then player 1 will be left with 1 (or 2).
So, final score of player 1 is 1 + 2 = 3, and player 2 is 5.
Hence, player 1 will never be the winner and you need to return False.
Example 2:
Input: [1, 5, 233, 7]
Output: True
Explanation: Player 1 first chooses 1. Then player 2 have to choose between 5 and 7. No matter which number player 2 choose, player 1 can choose 233.
Finally, player 1 has more score (234) than player 2 (12), so you need to return True representing player1 can win.
Note:
1 <= length of the array <= 20.
Any scores in the given array are non-negative integers and will not exceed 10,000,000.
If the scores of both players are equal, then player 1 is still the winner.

思路分析

题目很长,简单来说,就是给出一个数组,两个人从数组的首端或尾端依次选取数作为分数,选择后的数被移除,形成新的数组,直到数组元素被选完,问最后选手1得到的总分数是否能大于选手2(两人的 选取思路都是选择使最后分数总和最大的数)?

首先我们要明白贪婪算法是不可行的,当前最优不代表全局最优,因此这种思路放弃,因为问题的最终解依赖于子问题的解,因此很容易想到动态规划来解,我们从最终状态开始推导,最终选手1和选手2各自选择了一个数(我们不能够确定先后顺序),如果选手1赢,那么必然有 p1.all>p2.all,所以有p1.all-p2.all>0,因此我们只需要得到两位选手最终的总得分,并相减即可,因为不能够确定选择哪个数会使最终结果最优,因此计算了所有可能结果,具体实现如下:

    bool PredictTheWinner(vector<int>& nums) {        vector<vector<int>> memory(nums.size(),vector<int>(nums.size(),-1));        return helper( nums,0,nums.size()-1,memory)>=0;    }    int helper(vector<int>& nums,int s,int e,vector<vector<int>>&memory) {        if(memory[s][e]==-1)            memory[s][e] = s==e?nums[s] :max(nums[s]-helper(nums,s+1,e,memory),nums[e]-helper(nums,s,e-1,memory));         return memory[s][e];    }

代码中使用额外存储避免重复计算问题。

0 0
原创粉丝点击