本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章中,我不仅会讲解多种解题思路及其优化,还会用多种编程语言实现题解,涉及到通用解法时更将归纳总结出相应的算法模板。
为了方便在PC上运行调试、分享代码文件,我还建立了相关的仓库。在这一仓库中,你不仅可以看到LeetCode原题链接、题解代码、题解文章链接、同类题目归纳、通用解法总结等,还可以看到原题出现频率和相关企业等重要信息。如果有其他优选题解,还可以一同分享给他人。
由于本系列文章的内容随时可能发生更新变动,欢迎关注和收藏征服LeetCode系列文章目录一文以作备忘。
Alice and Bob continue their games with piles of stones. There are a number of piles arranged in a row, and each pile has a positive integer number of stones piles[i]
. The objective of the game is to end with the most stones.
Alice and Bob take turns, with Alice starting first. Initially, M = 1
.
On each player’s turn, that player can take all the stones in the first X
remaining piles, where 1 <= X <= 2M
. Then, we set M = max(M, X)
.
The game continues until all the stones have been taken.
Assuming Alice and Bob play optimally, return the maximum number of stones Alice can get.
Example 1:
Input: piles = [2,7,9,4,4] Output: 10 Explanation: If Alice takes one pile at the beginning, Bob takes two piles, then Alice takes 2 piles again. Alice can get 2 + 4 + 4 = 10 piles in total. If Alice takes two piles at the beginning, then Bob can take all three piles left. In this case, Alice get 2 + 7 = 9 piles in total. So we return 10 since it's larger.
Example 2:
Input: piles = [1,2,3,4,5,100] Output: 104
Constraints:
1 <= piles.length <= 100
1 <= piles[i] <= 104
题意:爱丽丝和鲍勃继续他们的石子游戏。许多堆石子 排成一行,每堆都有正整数颗石子 piles[i]
。游戏以谁手中的石子最多来决出胜负。爱丽丝和鲍勃轮流进行,爱丽丝先开始。最初,M = 1
。在每个玩家的回合中,该玩家可以拿走剩下的 前 X
堆的所有石子,其中 1 <= X <= 2M
。然后,令 M = max(M, X)
。
游戏一直持续到所有石子都被拿走。假设爱丽丝和鲍勃都发挥出最佳水平,返回爱丽丝可以得到的最大数量的石头。
解法1 博弈论+DFS+记忆化搜索
这种博弈游戏,假设双方都发挥最佳水平、都极其聪明,因此先手在做出最佳决策时(拿走一部分石头时),必须考虑后手的反映。后手也要考虑到先手紧随其后的反映。而且,先后手在做出决策时遇到的局面是无差别的、同质的,因此可以使用递归。
考虑最简单的情形,当最后剩下的石碓小于等于 2 M 2M 2M 时,玩家当前必然是把剩下的石子全部拿走最划算。接着考虑一般的情形,当前玩家想要拿到最多石头,则要综合所有可能:从第 i i i 堆开始,他分别取走 x = 1 , 2 , … , 2 m x =1,2,\dots, 2m x=1,2,…,2m 堆石头——当前玩家要做出选择,拿多少堆石头,这取决于「对方玩家分别从 i + 1 , i + 2 , … , i + 2 m i + 1, i + 2,\dots, i+2m i+1,i+2,…,i+2m 堆开始、最多拿走 max ( x , m ) \max(x, m) max(x,m) 堆石头,且同样做出最佳决策、能拿到的所有最多石头数中的最小者 t e m p temp temp 」。就是说,他拿多少堆石头,要使得对方玩家拿到的石头数最少为 t e m p temp temp ,而他后面能拿到的石头数,等于后面的所有石头数减去对方玩家拿到的石头数 t e m p temp temp 。
具体实现中,我们要先求出后缀和数组,然后使用 dfs(0,1)
求出爱丽丝能拿到的最多石头。
class Solution {
private:
vector<