[M博弈论] lc877. 石子游戏(博弈论+区间dp+好题+思维)

Posted Ypuyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[M博弈论] lc877. 石子游戏(博弈论+区间dp+好题+思维)相关的知识,希望对你有一定的参考价值。

1. 题目来源

链接:877. 石子游戏

2. 题目解析

本题可以偷鸡。

博弈论:

  • 由于序列是偶数长度,且只能从两端开始选。假设下标从 1 开始,那么先手玩家一定能够在两端选择 一奇一偶 的下标,有两种情况。而后手玩家就只能在两端选择 同奇同偶 的下标。

  • 所以,先手玩家在第一次操作时就能够计算 奇数下标和偶数下标 的和哪个大,每一次决策都限制后手玩家只能选择最优奇偶性序列的对立面即可。


区间 dp

  • f[l, r] 表示在区间 [l, r] 之间先手玩家在最坏情况下的最大得分和后手玩家最大得分的差值
  • 如果 f[l, r] > 0 说明先手胜利,=0 则为平局,<0 则为先手失败
  • 状态转移:当前玩家 f[i][j] 现在只能在 i 位置选,j 位置选。
    • 选择 i 位置的话,剩余的区间是 [i+1, j],考虑 f[i+1][j] 这个状态,是选完 i 之后,此时的后手玩家作为先手玩家与目前的先手玩家的最大得分差值(有点扰,多读几遍),假设为 B-A,是针对后手玩家来讲最好的情况。那么先手玩家目前最坏的得分差值其实就是 A-B,相差一个负号,即先手玩家选完 i 位置的数后,最坏的得分差值就是 w[i]+(A-B) = w[i]-f[i+1][j]
    • 注意这是区间 dp,短区间的状态已经被计算出来了。 且长区间需要短区间的状态,也是区间 dp 的经典应用条件。
    • 同理,选择 j 的话,转移应该是 w[j]-f[i][j-1]
  • 最后只需要判断 f[0][n - 1]>0 即可知道是否先手必胜。

针对博弈论问题,若有必胜、必败存在,一定是在最坏情况下能必胜,那就一定能必胜。即只需要保证最坏情况下最好就能判断胜负状态。


时间复杂度: O ( n 2 ) O(n^2) O(n2) O ( 1 ) O(1) O(1)

空间复杂度: O ( 1 ) O(1) O(1)


区间 dp O ( n 2 ) O(n^2) O(n2)

class Solution {
public:
    bool stoneGame(vector<int>& piles) {
        int n = piles.size();
        vector<vector<int>> f(n, vector<int>(n));

        for (int len = 1; len <= n; len ++ ) 
            for (int i = 0; i + len - 1 < n; i ++ ) {
                int j = i + len - 1;
                if (len == 1) f[i][j] = piles[i];
                else f[i][j] = max(piles[i] - f[i + 1][j], piles[j] - f[i][j - 1]);
            }
        
        return f[0][n - 1] > 0;
    }
};

O ( 1 ) O(1) O(1)

class Solution {
public:
    bool stoneGame(vector<int>& piles) {
        return true;
    }
};

以上是关于[M博弈论] lc877. 石子游戏(博弈论+区间dp+好题+思维)的主要内容,如果未能解决你的问题,请参考以下文章

HDU 2176 取(m堆)石子游戏 博弈

ACM取石子 - 博弈论

(HDU - 2176)取(m堆)石子游戏(尼姆博弈)

ACM-尼姆博弈之取(m堆)石子游戏——hdu2176

HDU 2176 取(m堆)石子游戏 尼姆博弈

取(m堆)石子游戏 HDU2176(Nim博弈)