LeetCode 1690. 石子游戏 VII (动态规划、博弈论)

文章目录

      • 题目描述

题目描述

石子游戏中,爱丽丝和鲍勃轮流进行自己的回合,爱丽丝先开始 。

有 n 块石子排成一排。每个玩家的回合中,可以从行中 移除 最左边的石头或最右边的石头,并获得与该行中剩余石头值之 和 相等的得分。当没有石头可移除时,得分较高者获胜。

鲍勃发现他总是输掉游戏(可怜的鲍勃,他总是输),所以他决定尽力 减小得分的差值 。爱丽丝的目标是最大限度地 扩大得分的差值 。

给你一个整数数组 stones ,其中 stones[i] 表示 从左边开始 的第 i 个石头的值,如果爱丽丝和鲍勃都 发挥出最佳水平 ,请返回他们 得分的差值 。

示例一:

输入:stones = [5,3,1,4,2]
输出:6
解释:
- 爱丽丝移除 2 ,得分 5 + 3 + 1 + 4 = 13 。游戏情况:爱丽丝 = 13 ,鲍勃 = 0 ,石子 = [5,3,1,4] 。
- 鲍勃移除 5 ,得分 3 + 1 + 4 = 8 。游戏情况:爱丽丝 = 13 ,鲍勃 = 8 ,石子 = [3,1,4] 。
- 爱丽丝移除 3 ,得分 1 + 4 = 5 。游戏情况:爱丽丝 = 18 ,鲍勃 = 8 ,石子 = [1,4] 。
- 鲍勃移除 1 ,得分 4 。游戏情况:爱丽丝 = 18 ,鲍勃 = 12 ,石子 = [4] 。
- 爱丽丝移除 4 ,得分 0 。游戏情况:爱丽丝 = 18 ,鲍勃 = 12 ,石子 = [] 。
得分的差值 18 - 12 = 6 。

示例二:

输入:stones = [7,90,5,1,100,10,10,2]
输出:122

数据范围:

n == stones.length
2 <= n <= 1000
1 <= stones[i] <= 1000

题目分析:
这道题涉及到了博弈论和动态规划,视频讲解参考,博弈论需要记住的只有一点:在最坏的情况中取最好的情况,那么我们对这道题目进行动态规划分析。
LeetCode 1690. 石子游戏 VII (动态规划、博弈论)_第1张图片
代码:

class Solution {
public:
    int stoneGameVII(vector<int>& s) {
        int n = s.size();
        
        // 定义前缀和数组和动态规划数组
        vector<int> sum(n + 1 , 0);
        vector<vector<int> > f(n + 1 , vector<int>(n + 1 , 0));
        
        // 处理前缀和
        for(int i = 1; i <= n; i++) sum[i] = sum[i-1] + s[i-1];
        
        // 先遍历长度,长度为1的话,取之后可得到的为0,所以从2开始遍历
        for(int len = 2; len <= n; len++)
        {
            for(int i = 1; i + len - 1 <= n; i++)
            {
                int j = i + len - 1; // 右端点
                // 在最坏情况中取最好的情况
                f[i][j] = max(sum[j] - sum[i] - f[i+1][j] , sum[j-1] - sum[i-1] - f[i][j-1]);
            }
        }
        return f[1][n];
    }
};

你可能感兴趣的:(动态规划,算法,leetcode)