环形石子合并(最大得分,每次合并相邻两堆,合并得分是两堆石子数量之和的平方)
字数 1951 2025-12-13 13:20:36

环形石子合并(最大得分,每次合并相邻两堆,合并得分是两堆石子数量之和的平方)


1. 题目描述

有一个环形石子堆数组 stones[0..n-1],其中 stones[i] 表示第 i 堆石子的数量。
现在你需要将这些石子堆合并成一堆,合并规则如下:

  • 每次只能合并相邻的两堆石子。
  • 合并的得分是这两堆石子数量之和的平方(即 (a + b)^2)。
  • 合并后的新堆石子数量为两堆之和,并放在原来的位置参与后续合并。
  • 由于是环形,首尾石子堆是相邻的。

问:将所有石子堆合并成一堆的最大得分是多少。


2. 问题分析

这是一个区间DP问题,但因为有“环形”条件,需要特殊处理。

线性版本(非环形)的合并规则为:

  • dp[l][r] 表示合并区间 [l, r] 内的石子成一堆的最大得分
  • 区间长度从 2 到 n 枚举。
  • 每次合并时,将区间分成左右两部分,分别先合并成两堆,再将这两堆合并,得分是这两堆石子总数的平方。

环形时,我们只需将原数组复制一份接在后面,在长度 2n 的数组上做线性DP,然后枚举所有长度为 n 的区间,求最大值即可。


3. 状态定义

设原数组长度为 n,构造新数组 a[0..2n-1],其中

a[i] = stones[i % n]  (i = 0..2n-1)

前缀和 prefix[i]a[0..i] 的和,方便求区间和。

定义 dp[l][r] 表示将 a[l..r] 合并成一堆的最大得分


4. 状态转移

对于区间 [l, r]

  • 如果 l == r,则只有一堆石子,不需要合并,得分 = 0。

  • 否则,我们最后一次合并是将两堆(分别来自 [l, k][k+1, r])合并成一堆。
    这两堆的石子总数分别为:

    sum_left = prefix[k] - (l > 0 ? prefix[l-1] : 0)
    sum_right = prefix[r] - prefix[k]
    

    但更简单的做法是:我们不需要提前知道左右两堆的数量,因为最后一步的得分等于整个区间和的平方:

    最后一步得分 = (sum(l, r)) ^ 2
    

    其中 sum(l, r)a[l..r] 的总和,可以用前缀和快速计算。

    那么:

    dp[l][r] = max_{k = l .. r-1} { dp[l][k] + dp[k+1][r] } + (sum(l, r))^2
    

    含义是:先分别合并 [l,k][k+1,r] 得到两堆,再合并这两堆得到最终一堆,最后一步得分是总和的平方。


5. 边界与初始化

  • 长度为 1 的区间:dp[l][l] = 0
  • 计算顺序:按区间长度 len 从 2 到 n(环形时我们在 2n 的数组上做到长度为 n 为止,但环形答案需要从每个起点取长度 n 的区间)。

6. 环形处理

在原数组后面复制一份得到长度 2n 的数组,做线性 DP 时,dp[l][r] 只在 r - l + 1 <= n 时计算(否则区间长度超过 n,不合法)。

最后答案:

ans = max_{i=0}^{n-1} dp[i][i + n - 1]

即枚举每个起点,合并连续 n 堆成一堆的最大得分。


7. 举例说明

假设原数组 stones = [1, 2, 3],n=3。
扩展数组 a = [1, 2, 3, 1, 2, 3]

前缀和 prefix = [1, 3, 6, 7, 9, 12]

计算 dp[0][2](合并前 3 堆):

长度 2 区间:

  • dp[0][1]:合并 a[0],a[1] = 1,2
    总和 = 3,最后得分 = 3^2 = 9。
    dp[0][1] = 0 + 0 + 9 = 9
  • dp[1][2]:合并 a[1],a[2] = 2,3
    总和 = 5,得分 = 25。
    dp[1][2] = 0 + 0 + 25 = 25

长度 3 区间 dp[0][2]
总和 = 6,总和平方 = 36。
枚举 k:

  • k=0:dp[0][0]+dp[1][2] = 0 + 25 = 25,再加 36 → 61
  • k=1:dp[0][1]+dp[2][2] = 9 + 0 = 9,再加 36 → 45
    取最大 61。

类似可计算其他起点。
最终答案取:

max(dp[0][2], dp[1][3], dp[2][4])

注意 dp[3][5] 是 a[3..5] 即 [1,2,3] 与 dp[0][2] 相同,因环形对称,不必重复。

计算后可得最大得分。


8. 时间复杂度与空间优化

  • 时间复杂度 O(n^3)(枚举起点、长度、分割点),n 是原数组长度,在 2n 数组上计算长度 ≤ n 的区间,总 O((2n) * n^2) = O(n^3)。
  • 空间复杂度 O(n^2)。

9. 关键点总结

  1. 环形问题转化为长度为 2n 的线性问题。
  2. 区间DP状态表示合并区间成一堆的最大得分。
  3. 转移时最后一步得分是整个区间和的平方,而不是左右两堆和的乘积(注意与“合并得分是两堆石子数量之和”不同,这里是平方,所以是固定的,与分界点无关,但分界点影响左右子区间的得分)。
  4. 最终答案是所有长度为 n 的区间的最大值。
环形石子合并(最大得分,每次合并相邻两堆,合并得分是两堆石子数量之和的平方) 1. 题目描述 有一个环形石子堆数组 stones[0..n-1] ,其中 stones[i] 表示第 i 堆石子的数量。 现在你需要将这些石子堆合并成一堆,合并规则如下: 每次只能合并 相邻 的两堆石子。 合并的 得分 是这两堆石子数量之和的 平方 (即 (a + b)^2 )。 合并后的新堆石子数量为两堆之和,并放在原来的位置参与后续合并。 由于是环形,首尾石子堆是相邻的。 问:将所有石子堆合并成一堆的 最大得分 是多少。 2. 问题分析 这是一个 区间DP 问题,但因为有“环形”条件,需要特殊处理。 线性版本 (非环形)的合并规则为: 用 dp[l][r] 表示合并区间 [l, r] 内的石子成一堆的 最大得分 。 区间长度从 2 到 n 枚举。 每次合并时,将区间分成左右两部分,分别先合并成两堆,再将这两堆合并,得分是这两堆石子总数的平方。 环形时,我们只需将原数组复制一份接在后面,在长度 2n 的数组上做线性DP,然后枚举所有长度为 n 的区间,求最大值即可。 3. 状态定义 设原数组长度为 n ,构造新数组 a[0..2n-1] ,其中 前缀和 prefix[i] 为 a[0..i] 的和,方便求区间和。 定义 dp[l][r] 表示将 a[l..r] 合并成一堆的 最大得分 。 4. 状态转移 对于区间 [l, r] : 如果 l == r ,则只有一堆石子,不需要合并,得分 = 0。 否则,我们最后一次合并是将两堆(分别来自 [l, k] 和 [k+1, r] )合并成一堆。 这两堆的石子总数分别为: 但更简单的做法是:我们 不需要提前知道左右两堆的数量 ,因为最后一步的得分等于整个区间和的平方: 其中 sum(l, r) 是 a[l..r] 的总和,可以用前缀和快速计算。 那么: 含义是:先分别合并 [l,k] 和 [k+1,r] 得到两堆,再合并这两堆得到最终一堆,最后一步得分是总和的平方。 5. 边界与初始化 长度为 1 的区间: dp[l][l] = 0 。 计算顺序:按区间长度 len 从 2 到 n (环形时我们在 2n 的数组上做到长度为 n 为止,但环形答案需要从每个起点取长度 n 的区间)。 6. 环形处理 在原数组后面复制一份得到长度 2n 的数组,做线性 DP 时, dp[l][r] 只在 r - l + 1 <= n 时计算(否则区间长度超过 n,不合法)。 最后答案: 即枚举每个起点,合并连续 n 堆成一堆的最大得分。 7. 举例说明 假设原数组 stones = [1, 2, 3] ,n=3。 扩展数组 a = [1, 2, 3, 1, 2, 3] 。 前缀和 prefix = [1, 3, 6, 7, 9, 12] 。 计算 dp[0][2] (合并前 3 堆): 长度 2 区间: dp[0][1] :合并 a[ 0],a[ 1 ] = 1,2 总和 = 3,最后得分 = 3^2 = 9。 dp[0][1] = 0 + 0 + 9 = 9 。 dp[1][2] :合并 a[ 1],a[ 2 ] = 2,3 总和 = 5,得分 = 25。 dp[1][2] = 0 + 0 + 25 = 25 。 长度 3 区间 dp[0][2] : 总和 = 6,总和平方 = 36。 枚举 k: k=0: dp[0][0]+dp[1][2] = 0 + 25 = 25 ,再加 36 → 61 k=1: dp[0][1]+dp[2][2] = 9 + 0 = 9 ,再加 36 → 45 取最大 61。 类似可计算其他起点。 最终答案取: 注意 dp[ 3][ 5] 是 a[ 3..5] 即 [ 1,2,3] 与 dp[ 0][ 2 ] 相同,因环形对称,不必重复。 计算后可得最大得分。 8. 时间复杂度与空间优化 时间复杂度 O(n^3)(枚举起点、长度、分割点),n 是原数组长度,在 2n 数组上计算长度 ≤ n 的区间,总 O((2n) * n^2) = O(n^3)。 空间复杂度 O(n^2)。 9. 关键点总结 环形问题转化为长度为 2n 的线性问题。 区间DP状态表示合并区间成一堆的最大得分。 转移时最后一步得分是 整个区间和的平方 ,而不是左右两堆和的乘积(注意与“合并得分是两堆石子数量之和”不同,这里是平方,所以是固定的,与分界点无关,但分界点影响左右子区间的得分)。 最终答案是所有长度为 n 的区间的最大值。