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

本文探讨了石子游戏中先手玩家如何利用博弈论和区间动态规划(DP)策略确保必胜。通过计算奇偶数之和,先手玩家每次选择都能限制后手,最终判断f[0][n-1]的正负来决定胜负。时间复杂度为O(n^2),空间复杂度为O(1)。
摘要由CSDN通过智能技术生成

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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ypuyu

如果帮助到你,可以请作者喝水~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值