取分数博弈--动态规划

Posted C_YCBX Py_YYDS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了取分数博弈--动态规划相关的知识,希望对你有一定的参考价值。

题目

在这里插入图片描述

题目解析

  • dp[i][j]表示在数组nums[i]~nums[j]中当前先手玩家与另一玩家拿下分数的最大差值。
  • 所以存在以下dp关系:dp[i][j] = max(nums[i]-dp[i+1][j],nums[j]-dp[i][j-1]),表示取首和尾,由于dp的定义所以展开为dp[i][j] = 当前先手玩家得分-当前后手玩家得分,所以对于dp[i+1][j]或者dp[i][j-1]他们的先手就是dp[i][j]的后手,所以要得到先手-后手则需要取'-'
  • 存在的base case:dp[i][j]当i = j时,肯定是dp[i][j] = nums[i],而i>j时非法,我们赋值为0其余情况均为dp[i][j] = max(nums[i]-dp[i+1][j],nums[j]-dp[i][j-1])
  • 由base case得到遍历方向:要么斜着遍历要么反着遍历

反着遍历

class Solution {
public:
    bool PredictTheWinner(vector<int>& nums) {
        int n = nums.size();
        int dp[n][n];
        for(int i = 0; i < n; i++)
            dp[i][i] = nums[i];
        for(int i = n-2;i>=0;i--){
            for(int j=i+1;j<n;j++){
                dp[i][j] = max(nums[i]-dp[i+1][j],nums[j]-dp[i][j-1]);
            }
        }
        return dp[0][n-1] >= 0;
    }
};


斜着遍历

class Solution {
public:
    bool PredictTheWinner(vector<int>& nums) {
        int n = nums.size();
        int dp[n][n];
        for(int i = 0; i < n; i++)
            dp[i][i] = nums[i];
       for(int len = 1;len<=n-1;len++){
            for(int i=0,j=i+len;j<n;j++,i++){
                dp[i][j] = max(nums[i]-dp[i+1][j],nums[j]-dp[i][j-1]);
            }
        }
        return dp[0][n-1] >= 0;
    }
};

以上是关于取分数博弈--动态规划的主要内容,如果未能解决你的问题,请参考以下文章

动态规划之博弈问题

博弈问题--石头游戏(动态规划)

硬币游戏1(博弈论入门题)

Leetcode之动态规划(DP)专题-1025. 除数博弈(Divisor Game)

动态规划专题6:打气球的最大分数

分别用回溯法和动态规划求0/1背包问题(C语言代码)