合并相邻字符形成目标串的最小操作次数问题(相邻字符可合并,合并有成本,求最小总成本)
字数 5639 2025-12-18 19:23:46

合并相邻字符形成目标串的最小操作次数问题(相邻字符可合并,合并有成本,求最小总成本)

题目描述
给定一个由小写字母组成的源字符串 s,长度为 n。你可以重复进行以下操作:选择两个相邻的字符 c1c2,将它们合并成一个新字符,新字符可以是任意小写字母,但需要支付一定的成本。成本由一个 26×26 的矩阵 cost[26][26] 给出,其中 cost[i][j] 表示将字符 i'a' 对应索引 0,'z' 对应索引 25)和字符 j 合并为任意一个字符的固定成本。注意:合并后得到的新字符可以是任意字母,不影响后续操作的成本计算,即成本只与合并的两个原始字符有关,与生成的新字符无关。你的目标是通过一系列合并操作,将整个源字符串 s 最终合并成单个字符,求所需的最小总成本。

例如:

  • 输入:s = "ab"cost 矩阵中 cost[0][1] = 2(假设其余成本为 0)。
  • 输出:2
  • 解释:将 'a''b' 合并,成本为 2,得到单个字符,总成本为 2。

问题本质
这是一个典型的区间动态规划问题。我们需要将整个字符串通过不断合并相邻字符最终变成一个字符,每次合并的成本由被合并的两个字符决定。目标是找到一种合并顺序,使得总成本最小。


解题步骤

1. 状态定义
定义 dp[l][r] 表示将字符串 s 的子串 s[l:r](左闭右闭区间)合并成一个字符所需的最小成本。

  • 子串长度为 1 时,已经是一个字符,不需要合并,成本为 0。
  • 子串长度 > 1 时,我们需要通过若干次合并将其变成一个字符。

2. 状态转移
对于区间 [l, r],长度大于 1,如何将其合并成一个字符?
我们可以考虑最后一次合并操作:在合并过程的最后一步,我们将区间 [l, r] 分成两部分:[l, k][k+1, r],其中 l ≤ k < r

  • 首先,将 [l, k] 合并成一个字符(假设这个字符是 x)。
  • 然后,将 [k+1, r] 合并成一个字符(假设这个字符是 y)。
  • 最后,将 xy 合并,得到最终的一个字符。这一步的成本是 cost[charIndex(x)][charIndex(y)]

但是这里有个问题:在 DP 状态中,我们只记录了合并成一个字符的最小成本,但并没有记录这个字符是什么。而最后一步合并的成本依赖于 xy 的具体字符。
因此,我们需要扩展状态,记录合并后可能得到的字符。

3. 状态扩展
定义 dp[l][r][c] 表示将子串 s[l:r] 合并成字符 cc 是 0 到 25 的整数,代表小写字母)所需的最小成本。如果不可能合并成字符 c,则值为无穷大(表示不可行)。
那么最终答案是 min_{c} dp[0][n-1][c],即合并成任意字符的最小成本。

4. 状态转移方程

  • 如果区间长度为 1,即 l == r,那么只有当 c 等于 s[l] 对应的字符时,成本为 0;否则为无穷大(因为不能变成其他字符而不经过合并)。
  • 如果长度 > 1,我们需要考虑如何将区间分成两部分,并分别合并成两个字符,然后最后一步合并成 c
    但是注意:合并操作的成本只与合并的两个原始字符有关,而与合并后生成的新字符无关。也就是说,从字符 xy 合并,可以生成任意字符,且成本固定为 cost[x][y]
    因此,对于 dp[l][r][c],我们可以枚举最后一次合并的分割点 k,以及左边部分合并成的字符 a,右边部分合并成的字符 b,那么:
    dp[l][r][c] = min_{l ≤ k < r} min_{a, b} ( dp[l][k][a] + dp[k+1][r][b] + cost[a][b] )
    
    注意:这里合并成 c 并没有额外成本,因为 cost[a][b] 已经包含了合并 ab 的成本,并且合并后我们可以认为得到了字符 c(实际上合并后生成什么字符不影响后续,因为成本只与 ab 有关)。
    所以,c 其实在这个状态转移中并不影响成本,它只是表示我们最终想要得到字符 c。但题目不要求最终一定是特定字符,所以我们最终取所有 c 的最小值即可。
    实际上,我们可以简化状态:因为成本与合并成的字符无关,我们只需要知道合并成某个字符的最小成本,而最终答案就是所有字符的最小值。
    所以,状态可以简化为 dp[l][r] 表示将子串 [l, r] 合并成任意一个字符所需的最小总成本。转移时:
    dp[l][r] = min_{l ≤ k < r} ( dp[l][k] + dp[k+1][r] + minCostOfMerge(leftChar, rightChar) )
    
    但这里 leftCharrightChar 是左边区间合并成的字符和右边区间合并成的字符,而 minCostOfMerge(leftChar, rightChar) 是合并这两个字符的最小成本,但我们不知道左边和右边分别合并成了什么字符。
    所以,我们仍然需要记录合并成的字符信息。

5. 优化状态转移
定义 dp[l][r][c] 为将子串合并成字符 c 的最小成本。
转移方程:
对于每个区间 [l, r],每个字符 c,枚举分割点 k,以及左边字符 a,右边字符 b,则:

dp[l][r][c] = min_{l ≤ k < r} min_{a, b} ( dp[l][k][a] + dp[k+1][r][b] + cost[a][b] )

这里 c 并不出现在等式右边,因为合并 ab 的成本与生成的新字符无关。但注意:我们要求最终是字符 c,而合并 ab 可以生成任意字符,所以只要我们选择 ab 使得合并后可以生成 c 就行?但题目没有限制生成的字符,所以实际上我们不需要关心生成的字符是什么,因为最终字符可以是任意字符。
因此,dp[l][r][c] 对于不同的 c 其实值是一样的?并不是,因为不同的 c 对应的合并路径可能不同,但成本只取决于合并的两个字符,与生成的字符无关,所以对于给定的区间,合并成不同字符的最小成本可能不同,因为为了得到特定字符,可能需要不同的合并顺序。
但在这个问题中,由于合并成本与生成的字符无关,为了得到字符 c,我们可以在最后一步任意选择 ab,只要成本最小即可,而不必关心 ab 是什么。
所以,我们可以将状态再简化:dp[l][r] 表示将区间合并成一个字符的最小成本,而不关心这个字符是什么。
转移时,我们枚举分割点 k,以及左边合并成的字符 a 和右边合并成的字符 b,但 ab 是什么?我们不知道,但我们可以从子问题知道:将左边区间合并成字符 a 的最小成本是 dpLeft[a],类似右边是 dpRight[b]
但这样我们需要在状态中记录字符信息,否则无法知道合并成特定字符的成本。
所以,我们必须用三维状态 dp[l][r][c]

6. 最终的状态转移方程
初始化:对于长度为 1 的区间 [i, i]dp[i][i][s[i]] = 0,其他字符为无穷大。
对于区间 [l, r],长度 len 从 2 到 n,枚举分割点 k,枚举字符 ab,则:

dp[l][r][c] = min(dp[l][r][c], dp[l][k][a] + dp[k+1][r][b] + cost[a][b])

注意:这里 c 是什么?实际上,合并 ab 后,我们可以认为得到了字符 c,但 c 可以是任意字符,且成本与 c 无关。所以,我们可以在计算完 dp[l][r][c] 后,对于所有 c 取相同值?不对,因为 dp[l][k][a]dp[k+1][r][b] 可能对于不同的 ab 不同,所以 dp[l][r][c] 可能依赖于 c,但成本项 cost[a][b]c 无关。
实际上,对于固定的 ab,合并成本固定,所以 dp[l][r][c] 对于所有 c 都是一样的,因为我们可以将 ab 合并,并声称得到了字符 c
因此,我们可以进一步简化:状态 dp[l][r] 表示合并成一个字符的最小成本,转移时:

dp[l][r] = min_{l ≤ k < r} ( min_{a, b} ( dp[l][k][a] + dp[k+1][r][b] + cost[a][b] ) )

这里 dp[l][k][a] 是子区间合并成字符 a 的最小成本,但我们并没有在 dp[l][r] 中记录字符信息。
所以,我们需要维护一个辅助数组 best[l][r][a] 表示将区间合并成字符 a 的最小成本,然后计算 dp[l][r] 时,枚举 ab,取 best[l][k][a] + best[k+1][r][b] + cost[a][b] 的最小值。
但最后,dp[l][r] 就是 min_a best[l][r][a]
所以,我们只需要维护 best[l][r][a] 即可。

7. 最终状态定义与转移
定义 f[l][r][c] 表示将子串 s[l..r] 合并成字符 c 的最小成本。
初始化:f[i][i][s[i]] = 0,其他为无穷大。
转移:对于区间 [l, r],枚举分割点 k,枚举左边字符 a,右边字符 b,则:

f[l][r][c] = min_{l ≤ k < r} min_{a, b} ( f[l][k][a] + f[k+1][r][b] + cost[a][b] )

这里 c 实际上可以是任意字符,因为合并 ab 后我们可以声明得到了字符 c,且成本与 c 无关。所以,对于不同的 cf[l][r][c] 的值是一样的。
那么我们可以省略 c,只记录 dp[l][r] 为合并成一个字符的最小成本,转移时:

dp[l][r] = min_{l ≤ k < r} ( min_{a, b} ( f[l][k][a] + f[k+1][r][b] + cost[a][b] ) )

但我们需要 f 来知道合并成特定字符的成本。
我们可以用 dp[l][r] 表示最小成本,同时用 charCost[l][r][c] 记录合并成字符 c 的最小成本,但 charCost[l][r][c] 可以通过 dp[l][r] 推导吗?不能,因为不同字符的成本路径可能不同。
所以,我们必须维护三维状态 f[l][r][c]

8. 实现细节

  • 状态维度:n x n x 26n 为字符串长度。
  • 初始化:f[i][i][s[i]-'a'] = 0,其他为 INF
  • 状态转移:枚举区间长度 len 从 2 到 n,枚举左端点 l,右端点 r = l + len - 1,枚举分割点 klr-1,枚举左边字符 a(0..25),右边字符 b(0..25),则:
    cost_merge = cost[a][b]
    for c in 0..25:
        f[l][r][c] = min(f[l][r][c], f[l][k][a] + f[k+1][r][b] + cost_merge)
    
    注意:这里合并成字符 c 并不需要额外条件,因为合并 ab 后我们可以认为得到 c,且成本不变。
    但这样会导致 f[l][r][c] 对于所有 c 都相同,因为对于同一个 (a, b),成本相同,且我们可以声明得到任意 c
    实际上,我们可以优化:我们不需要枚举 c,因为对于给定的 (a, b),我们可以将 f[l][k][a] + f[k+1][r][b] + cost[a][b] 同时更新到所有 f[l][r][c]
    但这样复杂度较高。我们可以改为:先计算 tmp = min_{a, b} ( f[l][k][a] + f[k+1][r][b] + cost[a][b] ),然后将这个 tmp 赋值给所有 f[l][r][c]
    但注意:不同的 (a, b) 组合可能得到不同的 tmp,我们要取所有 (a, b) 中最小的 tmp,然后 f[l][r][c] 就取这个最小 tmp
    所以,实际上 f[l][r][c] 对于不同 c 是一样的。
    那么我们可以将状态简化为 dp[l][r],表示合并成一个字符的最小成本。转移时:
    dp[l][r] = min_{l ≤ k < r} ( min_{a, b} ( f[l][k][a] + f[k+1][r][b] + cost[a][b] ) )
    
    但这里 f 是三维的,我们需要它来获取合并成特定字符的成本。但如果我们只关心最小成本,而不关心合并成什么字符,我们可以用 dp[l][r] 直接表示最小成本,并用另一个二维数组 best[l][r][c] 记录合并成字符 c 的最小成本,但这样又回到三维。
    一个巧妙的做法是:我们不需要记录合并成特定字符的成本,因为合并成任意字符的最小成本就是 dp[l][r],但转移时需要知道左右区间合并成什么字符,因为合并成本依赖于这两个字符。
    所以,我们不得不用三维状态。

9. 最终三维状态转移方程

f[l][r][c] = min_{l ≤ k < r} min_{a, b} ( f[l][k][a] + f[k+1][r][b] + cost[a][b] )

初始化:f[i][i][s[i]-'a'] = 0,其他为 INF
最终答案:min_{c} f[0][n-1][c]

时间复杂度:O(n^3 * 26^2),因为区间 O(n^2),分割点 O(n),枚举字符 a 和 b 是 2626。
空间复杂度:O(n^2
26)。

10. 示例推导
假设 s = "ab"cost[a][b] = 2,其他为 0。
初始化:f[0][0]['a'] = 0f[1][1]['b'] = 0
计算区间 [0,1]:
枚举 k=0,左边字符 a='a',右边字符 b='b',则 cost = 2,所以 f[0][1][c] = min( f[0][0]['a'] + f[1][1]['b'] + 2 ) = 2,对所有 c 都一样。
最终答案:min_c f[0][1][c] = 2

11. 核心要点

  • 因为合并成本只依赖于被合并的两个字符,与生成的新字符无关,所以状态转移时不需要关心生成什么字符。
  • 但为了计算合并成本,我们需要知道左右两部分合并成的字符,所以状态必须记录合并成的字符。
  • 最终答案是所有可能字符的最小成本。

总结
本题是区间 DP 的典型应用,通过三维状态记录区间合并成特定字符的最小成本,转移时枚举分割点和左右字符组合,加上合并成本,最终取最小值。通过合理定义状态,我们可以正确处理合并操作的成本依赖问题。

合并相邻字符形成目标串的最小操作次数问题(相邻字符可合并,合并有成本,求最小总成本) 题目描述 给定一个由小写字母组成的源字符串 s ,长度为 n 。你可以重复进行以下操作:选择两个 相邻 的字符 c1 和 c2 ,将它们合并成一个新字符,新字符可以是任意小写字母,但需要支付一定的成本。成本由一个 26×26 的矩阵 cost[26][26] 给出,其中 cost[i][j] 表示将字符 i ( 'a' 对应索引 0, 'z' 对应索引 25)和字符 j 合并为 任意一个字符 的固定成本。注意:合并后得到的新字符可以是任意字母,不影响后续操作的成本计算,即成本只与合并的两个原始字符有关,与生成的新字符无关。你的目标是通过一系列合并操作,将整个源字符串 s 最终合并成 单个字符 ,求所需的最小总成本。 例如: 输入: s = "ab" , cost 矩阵中 cost[0][1] = 2 (假设其余成本为 0)。 输出:2 解释:将 'a' 和 'b' 合并,成本为 2,得到单个字符,总成本为 2。 问题本质 这是一个典型的区间动态规划问题。我们需要将整个字符串通过不断合并相邻字符最终变成一个字符,每次合并的成本由被合并的两个字符决定。目标是找到一种合并顺序,使得总成本最小。 解题步骤 1. 状态定义 定义 dp[l][r] 表示将字符串 s 的子串 s[l:r] (左闭右闭区间)合并成 一个字符 所需的最小成本。 子串长度为 1 时,已经是一个字符,不需要合并,成本为 0。 子串长度 > 1 时,我们需要通过若干次合并将其变成一个字符。 2. 状态转移 对于区间 [l, r] ,长度大于 1,如何将其合并成一个字符? 我们可以考虑最后一次合并操作:在合并过程的最后一步,我们将区间 [l, r] 分成两部分: [l, k] 和 [k+1, r] ,其中 l ≤ k < r 。 首先,将 [l, k] 合并成一个字符(假设这个字符是 x )。 然后,将 [k+1, r] 合并成一个字符(假设这个字符是 y )。 最后,将 x 和 y 合并,得到最终的一个字符。这一步的成本是 cost[charIndex(x)][charIndex(y)] 。 但是这里有个问题:在 DP 状态中,我们只记录了合并成一个字符的最小成本,但并没有记录这个字符是什么。而最后一步合并的成本依赖于 x 和 y 的具体字符。 因此,我们需要扩展状态,记录合并后可能得到的字符。 3. 状态扩展 定义 dp[l][r][c] 表示将子串 s[l:r] 合并成字符 c ( c 是 0 到 25 的整数,代表小写字母)所需的最小成本。如果不可能合并成字符 c ,则值为无穷大(表示不可行)。 那么最终答案是 min_{c} dp[0][n-1][c] ,即合并成任意字符的最小成本。 4. 状态转移方程 如果区间长度为 1,即 l == r ,那么只有当 c 等于 s[l] 对应的字符时,成本为 0;否则为无穷大(因为不能变成其他字符而不经过合并)。 如果长度 > 1,我们需要考虑如何将区间分成两部分,并分别合并成两个字符,然后最后一步合并成 c 。 但是注意:合并操作的成本只与合并的两个原始字符有关,而与合并后生成的新字符无关。也就是说,从字符 x 和 y 合并,可以生成任意字符,且成本固定为 cost[x][y] 。 因此,对于 dp[l][r][c] ,我们可以枚举最后一次合并的分割点 k ,以及左边部分合并成的字符 a ,右边部分合并成的字符 b ,那么: 注意:这里合并成 c 并没有额外成本,因为 cost[a][b] 已经包含了合并 a 和 b 的成本,并且合并后我们可以认为得到了字符 c (实际上合并后生成什么字符不影响后续,因为成本只与 a 和 b 有关)。 所以, c 其实在这个状态转移中并不影响成本,它只是表示我们最终想要得到字符 c 。但题目不要求最终一定是特定字符,所以我们最终取所有 c 的最小值即可。 实际上,我们可以简化状态:因为成本与合并成的字符无关,我们只需要知道合并成某个字符的最小成本,而最终答案就是所有字符的最小值。 所以,状态可以简化为 dp[l][r] 表示将子串 [l, r] 合并成任意一个字符所需的最小总成本。转移时: 但这里 leftChar 和 rightChar 是左边区间合并成的字符和右边区间合并成的字符,而 minCostOfMerge(leftChar, rightChar) 是合并这两个字符的最小成本,但我们不知道左边和右边分别合并成了什么字符。 所以,我们仍然需要记录合并成的字符信息。 5. 优化状态转移 定义 dp[l][r][c] 为将子串合并成字符 c 的最小成本。 转移方程: 对于每个区间 [l, r] ,每个字符 c ,枚举分割点 k ,以及左边字符 a ,右边字符 b ,则: 这里 c 并不出现在等式右边,因为合并 a 和 b 的成本与生成的新字符无关。但注意:我们要求最终是字符 c ,而合并 a 和 b 可以生成任意字符,所以只要我们选择 a 和 b 使得合并后可以生成 c 就行?但题目没有限制生成的字符,所以实际上我们不需要关心生成的字符是什么,因为最终字符可以是任意字符。 因此, dp[l][r][c] 对于不同的 c 其实值是一样的?并不是,因为不同的 c 对应的合并路径可能不同,但成本只取决于合并的两个字符,与生成的字符无关,所以对于给定的区间,合并成不同字符的最小成本可能不同,因为为了得到特定字符,可能需要不同的合并顺序。 但在这个问题中,由于合并成本与生成的字符无关,为了得到字符 c ,我们可以在最后一步任意选择 a 和 b ,只要成本最小即可,而不必关心 a 和 b 是什么。 所以,我们可以将状态再简化: dp[l][r] 表示将区间合并成一个字符的最小成本,而不关心这个字符是什么。 转移时,我们枚举分割点 k ,以及左边合并成的字符 a 和右边合并成的字符 b ,但 a 和 b 是什么?我们不知道,但我们可以从子问题知道:将左边区间合并成字符 a 的最小成本是 dpLeft[a] ,类似右边是 dpRight[b] 。 但这样我们需要在状态中记录字符信息,否则无法知道合并成特定字符的成本。 所以,我们必须用三维状态 dp[l][r][c] 。 6. 最终的状态转移方程 初始化:对于长度为 1 的区间 [i, i] , dp[i][i][s[i]] = 0 ,其他字符为无穷大。 对于区间 [l, r] ,长度 len 从 2 到 n,枚举分割点 k ,枚举字符 a 和 b ,则: 注意:这里 c 是什么?实际上,合并 a 和 b 后,我们可以认为得到了字符 c ,但 c 可以是任意字符,且成本与 c 无关。所以,我们可以在计算完 dp[l][r][c] 后,对于所有 c 取相同值?不对,因为 dp[l][k][a] 和 dp[k+1][r][b] 可能对于不同的 a 和 b 不同,所以 dp[l][r][c] 可能依赖于 c ,但成本项 cost[a][b] 与 c 无关。 实际上,对于固定的 a 和 b ,合并成本固定,所以 dp[l][r][c] 对于所有 c 都是一样的,因为我们可以将 a 和 b 合并,并声称得到了字符 c 。 因此,我们可以进一步简化:状态 dp[l][r] 表示合并成一个字符的最小成本,转移时: 这里 dp[l][k][a] 是子区间合并成字符 a 的最小成本,但我们并没有在 dp[l][r] 中记录字符信息。 所以,我们需要维护一个辅助数组 best[l][r][a] 表示将区间合并成字符 a 的最小成本,然后计算 dp[l][r] 时,枚举 a 和 b ,取 best[l][k][a] + best[k+1][r][b] + cost[a][b] 的最小值。 但最后, dp[l][r] 就是 min_a best[l][r][a] 。 所以,我们只需要维护 best[l][r][a] 即可。 7. 最终状态定义与转移 定义 f[l][r][c] 表示将子串 s[l..r] 合并成字符 c 的最小成本。 初始化: f[i][i][s[i]] = 0 ,其他为无穷大。 转移:对于区间 [l, r] ,枚举分割点 k ,枚举左边字符 a ,右边字符 b ,则: 这里 c 实际上可以是任意字符,因为合并 a 和 b 后我们可以声明得到了字符 c ,且成本与 c 无关。所以,对于不同的 c , f[l][r][c] 的值是一样的。 那么我们可以省略 c ,只记录 dp[l][r] 为合并成一个字符的最小成本,转移时: 但我们需要 f 来知道合并成特定字符的成本。 我们可以用 dp[l][r] 表示最小成本,同时用 charCost[l][r][c] 记录合并成字符 c 的最小成本,但 charCost[l][r][c] 可以通过 dp[l][r] 推导吗?不能,因为不同字符的成本路径可能不同。 所以,我们必须维护三维状态 f[l][r][c] 。 8. 实现细节 状态维度: n x n x 26 , n 为字符串长度。 初始化: f[i][i][s[i]-'a'] = 0 ,其他为 INF 。 状态转移:枚举区间长度 len 从 2 到 n,枚举左端点 l ,右端点 r = l + len - 1 ,枚举分割点 k 从 l 到 r-1 ,枚举左边字符 a (0..25),右边字符 b (0..25),则: 注意:这里合并成字符 c 并不需要额外条件,因为合并 a 和 b 后我们可以认为得到 c ,且成本不变。 但这样会导致 f[l][r][c] 对于所有 c 都相同,因为对于同一个 (a, b) ,成本相同,且我们可以声明得到任意 c 。 实际上,我们可以优化:我们不需要枚举 c ,因为对于给定的 (a, b) ,我们可以将 f[l][k][a] + f[k+1][r][b] + cost[a][b] 同时更新到所有 f[l][r][c] 。 但这样复杂度较高。我们可以改为:先计算 tmp = min_{a, b} ( f[l][k][a] + f[k+1][r][b] + cost[a][b] ) ,然后将这个 tmp 赋值给所有 f[l][r][c] 。 但注意:不同的 (a, b) 组合可能得到不同的 tmp ,我们要取所有 (a, b) 中最小的 tmp ,然后 f[l][r][c] 就取这个最小 tmp 。 所以,实际上 f[l][r][c] 对于不同 c 是一样的。 那么我们可以将状态简化为 dp[l][r] ,表示合并成一个字符的最小成本。转移时: 但这里 f 是三维的,我们需要它来获取合并成特定字符的成本。但如果我们只关心最小成本,而不关心合并成什么字符,我们可以用 dp[l][r] 直接表示最小成本,并用另一个二维数组 best[l][r][c] 记录合并成字符 c 的最小成本,但这样又回到三维。 一个巧妙的做法是:我们不需要记录合并成特定字符的成本,因为合并成任意字符的最小成本就是 dp[l][r] ,但转移时需要知道左右区间合并成什么字符,因为合并成本依赖于这两个字符。 所以,我们不得不用三维状态。 9. 最终三维状态转移方程 初始化: f[i][i][s[i]-'a'] = 0 ,其他为 INF 。 最终答案: min_{c} f[0][n-1][c] 。 时间复杂度:O(n^3 * 26^2),因为区间 O(n^2),分割点 O(n),枚举字符 a 和 b 是 26 26。 空间复杂度:O(n^2 26)。 10. 示例推导 假设 s = "ab" , cost[a][b] = 2 ,其他为 0。 初始化: f[0][0]['a'] = 0 , f[1][1]['b'] = 0 。 计算区间 [ 0,1 ]: 枚举 k=0,左边字符 a='a',右边字符 b='b',则 cost = 2,所以 f[0][1][c] = min( f[0][0]['a'] + f[1][1]['b'] + 2 ) = 2 ,对所有 c 都一样。 最终答案: min_c f[0][1][c] = 2 。 11. 核心要点 因为合并成本只依赖于被合并的两个字符,与生成的新字符无关,所以状态转移时不需要关心生成什么字符。 但为了计算合并成本,我们需要知道左右两部分合并成的字符,所以状态必须记录合并成的字符。 最终答案是所有可能字符的最小成本。 总结 本题是区间 DP 的典型应用,通过三维状态记录区间合并成特定字符的最小成本,转移时枚举分割点和左右字符组合,加上合并成本,最终取最小值。通过合理定义状态,我们可以正确处理合并操作的成本依赖问题。