• 预测赢家


    重新做一遍,两个月前做的已经忘记的差不多了。。。

    给定一个表示分数的非负整数数组。 玩家 1 从数组任意一端拿取一个分数,随后玩家 2 继续从剩余数组任意一端拿取分数,然后玩家 1 拿,…… 。每次一个玩家只能拿取一个分数,分数被拿取之后不再可取。直到没有剩余分数可取时游戏结束。最终获得分数总和最多的玩家获胜。

    给定一个表示分数的数组,预测玩家1是否会成为赢家。你可以假设每个玩家的玩法都会使他的分数最大化。

    输入:[1, 5, 2]
    输出:False
    解释:一开始,玩家1可以从1和2中进行选择。
    如果他选择 2(或者 1 ),那么玩家 2 可以从 1(或者 2 )和 5 中进行选择。如果玩家 2 选择了 5 ,那么玩家 1 则只剩下 1(或者 2 )可选。
    所以,玩家 1 的最终分数为 1 + 2 = 3,而玩家 25 。
    因此,玩家 1 永远不会成为赢家,返回 False 

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/predict-the-winner

    这道题很有意思,因为这涉及到一点博弈的感觉,一开始接触总觉得无处下手。看完答案之后我只能说,妙极了。

    这道题考虑的动态规划的求解,那么如何来定义base case,以及状态转移方程呢?

    首先,先引入另一道题887.石子游戏,这是预测赢家的一个特例,它多了两个限制条件,1.数组长度为偶数 2.数组加和为奇数(一定有一个人赢)

    这个题,只用一步就能求解,很有意思。

    1 class Solution {
    2 public:
    3     bool stoneGame(vector<int>& piles) {
    4         return true;
    5     }
    6 };

    这里有些数学的东西,很好玩。

    如图,4堆石子,分成两组,偶数为1,奇数为2.

    玩家1先手,判断玩家1是不是能赢。首先玩家1可以选择1或者2,如果选择了1,则玩家2只能从2中选一个,接下来玩家1又能从1,2进行选择。

    所以玩家1可以选择同一组,而玩家1完全可以通过计算哪一组的加和更大,选择哪一组,这样必然会胜利。

    故,回到这一题,我们可以知道,当数组长度为偶数时 return true;

    我们考虑奇数的情况

    dp[i][j]表示子数组[i...j]中的最大得分(不区分玩家1和玩家2,因为每一位玩家都是想得到最大分数的)

    那么对于数组只有一个元素时,dp[i][i]=num[i];

    状态转移方程:dp[i][j],可以选择num[i],temp1=num[i]-dp[i+1][j]//减去玩家2的分数;选择num[j],temp2=num[j]-dp[i][j-1]

    故dp[i][j]=max(temp1,temp2)

    所以我们的代码为:

     1 class Solution {
     2 public:
     3     bool PredictTheWinner(vector<int>& nums) {
     4         //dp table
     5         int n=nums.size();
     6         if(n%2==0||n==0)
     7             return true;
     8         int dp[n][n];
     9         for(int i=0;i<n;i++)
    10             dp[i][i]=nums[i];
    11         for(int i=n-2;i>=0;i--){
    12             for(int j=i+1;j<n;j++){
    13                 dp[i][j]=max((nums[i]-dp[i+1][j]),(nums[j]-dp[i][j-1]));
    14             }
    15         }
    16         return dp[0][n-1]>=0;
    17     }
    18 };
  • 相关阅读:
    202104-2 邻域均值
    202104-1 灰度直方图
    1384. 饲料调配
    1381. 阶乘
    264. 丑数 II
    1380. 邮票
    42 新安装的idea必备设置
    41 cmd中解除被占用的端口
    40 文件在线预览
    39 进度条使用
  • 原文地址:https://www.cnblogs.com/doris233/p/13971758.html
Copyright © 2020-2023  润新知