石子游戏 II
字数 1026 2025-11-13 02:21:41
石子游戏 II
题目描述:
给定一个整数数组 piles,表示一排石堆,其中 piles[i] 表示第 i 堆石子的数量。Alice 和 Bob 轮流进行回合,Alice 先手。在每个回合中,玩家可以取走前 X 堆石子,其中 1 <= X <= 2M,然后设置 M = max(M, X)。游戏持续到所有石子都被取完。假设 Alice 和 Bob 都发挥出最佳水平,返回 Alice 可以获得的最大石子数量。
解题过程:
-
问题分析:
- 这是一个博弈类区间动态规划问题,玩家每次可以从剩余石堆的开头取走 1 到 2M 堆石子。
- 状态需要包含:当前剩余石堆的起始位置和当前的 M 值。
-
状态定义:
- 定义
dp[i][m]表示从第i堆石子开始,当前 M 值为m时,当前玩家能获得的最大石子数量。 - 由于数组长度可能很大,我们需要优化状态表示。
- 定义
-
前缀和优化:
- 预处理前缀和数组
prefix,其中prefix[i]表示从第 0 堆到第 i-1 堆石子的总和。 - 这样,从第 i 堆到第 j-1 堆的石子总数可以快速计算为
prefix[j] - prefix[i]。
- 预处理前缀和数组
-
状态转移:
- 对于状态
dp[i][m],当前玩家可以取走x堆石子,其中1 <= x <= 2m。 - 取走前 x 堆石子后,获得石子总数为
prefix[i+x] - prefix[i]。 - 下一个状态是
dp[i+x][max(m, x)],表示对手在剩余石子上的最优表现。 - 状态转移方程:
dp[i][m] = max(当前获得石子数 + 剩余石子总数 - 对手最优解)
- 对于状态
-
具体实现:
- 使用记忆化搜索或自底向上的 DP。
- 基础情况:当
i == n(没有剩余石子)时,返回 0。 - 对于每个位置 i 和 m 值,遍历所有可能的 x(1 <= x <= 2m),计算当前选择的最优解。
-
时间复杂度优化:
- 直接实现的时间复杂度是 O(n³),可能超时。
- 优化:当 x 较大时,当前玩家可以直接取走所有剩余石子,提前终止循环。
-
最终结果:
- 初始状态是
dp[0][1],表示从第 0 堆开始,M 初始值为 1。 - Alice 能获得的最大石子数量就是
dp[0][1]。
- 初始状态是
通过这个详细的步骤,我们可以系统地解决石子游戏 II 问题,确保在双方都采取最优策略的情况下,计算出 Alice 能获得的最大石子数量。