专栏名称: 吴师兄学算法
和程序员小吴一起从初学者的角度学习算法,以动画的形式呈现解题的思路。每周四篇原创文章,期待你的鉴赏!
目录
相关文章推荐
壹读  ·  中产的保温杯,比iPhone还小了? ·  昨天  
新京报书评周刊  ·  我们为何渴望安稳,却又想要逃离? ·  3 天前  
新京报书评周刊  ·  几乎不识字的她,完成了一部关于自己的人生叙事 ·  5 天前  
十点读书会  ·  疯涨的黄金,受骗的年轻人 ·  2 天前  
51好读  ›  专栏  ›  吴师兄学算法

字节一面,人麻了。。。

吴师兄学算法  · 公众号  ·  · 2024-04-01 16:31

正文

大家好,我是吴师兄。

最近很多同学反馈美团、拼多多、字节的笔试题都非常非常难,没有掌握动态规划直接跪。。。

不过今年行情相较于去年好转了不少,好好准备,还是有挺多机会的,继续来今天的算法练习。

无论是 Dota、LOL 还是其它 MOBA 游戏,比赛中均存在着 Ban Pick 机制: 参与比赛的双方队伍通过数轮禁用/选取英雄后,最终确定游戏比赛的英雄阵容

这是一个斗智斗勇的环节,布置陷阱、各种套路与反制让很多没有玩过游戏的小伙伴也能享受电竞的魅力。

Ban Pick 就是为了能给对战双方创造出一个 平等的对战环境 ,因为如果没有这个环节,那么就变成了投硬币游戏,先手的一方具有 极大 的优势,可以选择版本强势英雄。

就像五子棋,如果是不带禁手的规则,那么 先手黑棋必胜 ,1992 年 Victor Allis 通过编程证明这一点,感兴趣的小伙伴也可以自己编程尝试证明。

在 LeetCode 里面也存在着这样一道题目, 先手必胜 ,这道题目是 LeetCode 第 877 号问题 石子游戏

依旧先给没有见过这道题目的小伙伴补充一下前置知识, 石子游戏 讲的是你和小伙伴两个人用几堆石子玩游戏,一共有偶数堆石子,排成一行;每堆都有正整数颗石子,数目为 piles[i] 。

游戏以谁手中的石子最多来决出胜负,由于石子的总数是奇数, 所以不存在平局

接下来,两个人轮流开始选择,假设 你先手 每回合你们都可以从行的开始或结束处取走整堆石头 ,直到没有更多的石子堆为止, 此时手中石子最多的玩家获胜

举个例子:

一开始,你只能选择拿前 5 颗或后 5 颗石子,假设你选择拿前 5 颗,那么就剩下的这一行石子就变成了这种样子。

如果你的对手选择拿走前 3 颗,那么剩下的是 [ 4 , 5 ],你拿走后 5 颗赢得 10 分,大于了对手的 3 + 4 = 7

如果你的对手选择拿走后 5 颗,那么剩下的是 [ 3 , 4 ],你拿走后 4 颗赢得 9 分,,大于了对手的 5 + 3 = 8

对于 [ 5 , 3 , 4 , 5 ] ,先手的你可以赢得比赛

题目让我们去判断一下,给定任意一个数组,假设你和对手都能发挥最佳水平,并且是你先手,最终赢得游戏的人是谁?

这道题目和我们昨天分析的 LeetCode 第 292 号问题 Nim 游戏 一样,是可以采取动态规划的思路来思考的,这里我就不展开讲了。

这道题目同样是一道博弈论的问题,答案只有一行代码, 先手必胜

class Solution {
    public boolean stoneGame(int[] piles) {
        // 先手必胜
        return true;
    }
}

详细分析一下。

由于石子的堆数为偶数,那么肯定是可以划分为 同样堆数的两个集合 ,奇数堆集合与偶数堆集合。

1、青色的序列都是奇数,是奇数堆集合。

2、绿色的序列都是偶数,是偶数堆集合。

再次注意,由于石子的堆数为偶数,那么一开始最左边的石子堆必然是奇数堆,最右边的石子堆必然是偶数堆。

每次在你选完对手再选完后,完成了一个回合,剩下的石子堆的堆数依旧是偶数。

这也就意味着,如果你选择了奇数序列开局,那么你 总可以把所有的奇数序列都选取。

比如,你选择了 1 号,如果对手选择 6 号,你可以选择奇数序列 5 号;如果对手选择 2 号,你可以选择奇数序列 3 号;







请到「今天看啥」查看全文