leetcode每日一题2029. 石子游戏 IX 博弈相对论 不战而屈人之兵

📖本篇内容:leetcode每日一题2029. 石子游戏 IX 游戏中博弈思想真的很重要~

📑 文章专栏:leetcode每日一题《打卡日常》

📆 最近更新:2022年1月19日 leetcode每日一题219. 存在重复元素 II 简单双百不过分吧 入门滑动窗口+ 哈希表存储

🙊个人简介:一只二本院校在读的大三程序猿,本着注重基础,打卡算法,分享技术作为个人的经验总结性的博文博主,虽然可能有时会犯懒,但是还是会坚持下去的,如果你很喜欢博文的话,建议看下面一行~(疯狂暗示QwQ)

🌇 点赞 👍 收藏 ⭐留言 📝 一键三连 关爱程序猿,从你我做起

🙊写在前面🙊

欧后~小付今天又看到了Alice和Bob没事闲的在下棋了,这俩人说多了都是泪,leetcode博弈创始题老祖,今天是他们的封神一战,自此之后,leetcode周赛再无出现博弈题,咱们来看看这道折磨人的中等题吧!

题目

  1. 石子游戏 IX

Alice 和 Bob 再次设计了一款新的石子游戏。现有一行 n 个石子,每个石子都有一个关联的数字表示它的价值。给你一个整数数组 stones ,其中stones[i]是第i个石子的价值。
Alice 和 Bob 轮流进行自己的回合,Alice 先手。每一回合,玩家需要从 stones 中移除任一石子。
如果玩家移除石子后,导致 所有已移除石子 的价值 总和 可以被 3 整除,那么该玩家就输掉游戏
如果不满足上一条,且移除后没有任何剩余的石子,那么 Bob将会直接获胜即便是在 Alice 的回合)。
假设两位玩家均采用最佳决策。如果 Alice 获胜,返回 true ;如果 Bob 获胜,返回 false 。

示例

示例1:

输入:stones = [2,1]
输出:true
解释:游戏进行如下:
- 回合 1:Alice 可以移除任意一个石子。
- 回合 2:Bob 移除剩下的石子。 
已移除的石子的值总和为 1 + 2 = 3 且可以被 3 整除。因此,Bob 输,Alice 获胜。

示例2:

输入:stones = [2]
输出:false
解释:Alice 会移除唯一一个石子,已移除石子的值总和为 2 。 
由于所有石子都已移除,且值总和无法被 3 整除,Bob 获胜。

示例3:

输入:stones = [5,1,2,4,3]
输出:false
解释:Bob 总会获胜。其中一种可能的游戏进行方式如下:
- 回合 1:Alice 可以移除值为 1 的第 2 个石子。已移除石子值总和为 1 。
- 回合 2:Bob 可以移除值为 3 的第 5 个石子。已移除石子值总和为 = 1 + 3 = 4 。
- 回合 3:Alices 可以移除值为 4 的第 4 个石子。已移除石子值总和为 = 1 + 3 + 4 = 8 。
- 回合 4:Bob 可以移除值为 2 的第 3 个石子。已移除石子值总和为 = 1 + 3 + 4 + 2 = 10.
- 回合 5:Alice 可以移除值为 5 的第 1 个石子。已移除石子值总和为 = 1 + 3 + 4 + 2 + 5 = 15.
Alice 输掉游戏,因为已移除石子值总和(15)可以被 3 整除,Bob 获胜。

提示

1 <= stones.length <= 10^5
1 <= stones[i] <= 10^4

📝思路📝

这是一道典型的博弈思想题,在题中,我们每次如果都要算加和的值再去向3取模无疑增大了空间以及算法难度,因此我们可以对每个石子的价值进行取模 3可以得知,当取模为0的值就是可以直接被3整除,而出现了 取模为1与取模2的值一对出现 则会出现被3整除的情况

因为Alice在先手、所以我们可以知道:他是不想使得自己凑出3的倍数的值并且在自己摸到最后一个石子之前想办法给Bob凑出整除3的值,而Bob呢,就是避免Alice给出的路,非要反其道而行之,不凑出与之模1对应的模2,模2对应的模1.,等待棋子摸完,Bob不战而屈人之兵。

⭐代码实现⭐

class Solution {
    public boolean stoneGameIX(int[] stones) {
        int [] mod = new int[3];
        //记录取模后能被3整除 取模为1,取模为2的个数
        for (int i : stones){
            mod[i%3]++;
        }
		//因为Alice先手,
		//如果没有 取模为 1 与 取模为 2的值
		//那么Alice永远凑不出 能被3整除的数字 使得Bob认输
		//那么结果肯定是Bob赢了。
        if (mod[1] == 0&& mod[2] == 0)return false;

		//对所有能被3整除的个数 取模2  
		//能被整除则说明到了Alice回合必须要找给Bob能凑出来的值
        if (mod[0] %2 == 0){
            return mod[1]!=0 && mod[2]!=0;
        }else {
        //反之到了Bob的回合Bob只需要满足每次多找到一个Alice所走的路不让他凑出3整除即可
            return Math.abs(mod[1]-mod[2])>2;
        }
    }
}

运行结果

在这里插入图片描述

🙊写在最后🙊

2022-1-20 今天小付打卡了哦~

美好的日出 美好的山河

都因有你存在 而璀璨 耀眼

最后

每天进步点 每天收获点

愿诸君 事业有成 学有所获

如果觉得不错 别忘啦一键三连哦~

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Alascanfu

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值