合并相邻同色方块的最小成本问题
字数 1548 2025-11-13 03:45:43

合并相邻同色方块的最小成本问题

题目描述:
给定一个颜色数组 colors 和一个成本数组 costs,其中 colors[i] 表示第 i 个方块的颜色,costs[i] 表示移除第 i 个方块的成本。游戏规则是:如果存在三个或更多连续同色方块,可以移除这些方块并获得移除成本的总和。移除后,左右两侧的方块会相邻。请计算通过最优的移除顺序,能够获得的最大总得分。

解题过程:

  1. 问题分析:
  • 这是一个典型的区间动态规划问题
  • 我们需要考虑在区间 [i, j] 内,通过最优的移除顺序能获得的最大得分
  • 关键点:当移除中间某个区间后,左右两侧可能会连接形成新的连续同色方块
  1. 状态定义:
    定义 dp[i][j] 表示在区间 [i, j] 内通过最优移除顺序能获得的最大得分

  2. 基础情况:

  • 当区间长度小于3时(即 j-i+1 < 3),无法移除任何方块,得分为0
  • dp[i][i] = 0,dp[i][i+1] = 0
  1. 状态转移:
    对于区间 [i, j],考虑以下几种情况:

情况1:直接移除整个区间(如果满足条件)
如果区间 [i, j] 内所有方块颜色相同且长度 ≥ 3,则:
dp[i][j] = sum(costs[i..j])

情况2:分割区间
对于所有可能的分割点 k (i ≤ k < j):
dp[i][j] = max(dp[i][j], dp[i][k] + dp[k+1][j])

情况3:移除中间部分后两侧合并
如果 colors[i] == colors[j],考虑移除中间区间 [l, r] 后,两侧的 i 和 j 相邻:
对于区间 [i, j],如果存在某个分割方式,移除中间部分后剩下的两端可以继续合并得分

更精确的状态转移:
dp[i][j] = max(
dp[i][j], // 初始值
// 情况1:直接得分(如果满足条件)
(如果区间内所有颜色相同且长度≥3 ? sum(costs[i..j]) : -∞),
// 情况2:分割得分
max_{i≤k<j} (dp[i][k] + dp[k+1][j]),
// 情况3:移除中间后合并得分
... // 这里需要更复杂的处理
)

  1. 优化状态设计:
    为了处理情况3,我们需要更精细的状态定义:
    定义 dp[i][j][k] 表示在区间 [i, j] 内,在区间左侧有 k 个与 colors[i] 同色的方块相连时能获得的最大得分

  2. 完整的状态转移方程:
    令 dp[i][j][k] 表示区间 [i, j],且区间左侧有 k 个与 colors[i] 同色的方块

  • 基础情况:当 i > j 时,dp[i][j][k] = 0

  • 状态转移:

    1. 先移除第 i 个方块:dp[i][j][k] = dp[i+1][j][0] + (如果 k ≥ 2 ? costs[i] : 0)

    2. 不移除第 i 个方块,寻找与 i 同色的位置 m:
      for m = i+1 to j:
      if colors[i] == colors[m]:
      dp[i][j][k] = max(dp[i][j][k],
      dp[i+1][m-1][0] + dp[m][j][k+1])

  1. 最终答案:
    dp[0][n-1][0],其中 n 是方块数量

  2. 实现细节:

  • 使用记忆化搜索或自底向上的DP
  • 注意边界条件处理
  • 时间复杂度:O(n³),空间复杂度:O(n²)

这个解法通过三维DP状态巧妙地处理了移除中间部分后两侧方块合并的情况,是这类"消消乐"类型问题的经典解法。

合并相邻同色方块的最小成本问题 题目描述: 给定一个颜色数组 colors 和一个成本数组 costs,其中 colors[ i] 表示第 i 个方块的颜色,costs[ i ] 表示移除第 i 个方块的成本。游戏规则是:如果存在三个或更多连续同色方块,可以移除这些方块并获得移除成本的总和。移除后,左右两侧的方块会相邻。请计算通过最优的移除顺序,能够获得的最大总得分。 解题过程: 问题分析: 这是一个典型的区间动态规划问题 我们需要考虑在区间 [ i, j ] 内,通过最优的移除顺序能获得的最大得分 关键点:当移除中间某个区间后,左右两侧可能会连接形成新的连续同色方块 状态定义: 定义 dp[ i][ j] 表示在区间 [ i, j ] 内通过最优移除顺序能获得的最大得分 基础情况: 当区间长度小于3时(即 j-i+1 < 3),无法移除任何方块,得分为0 dp[ i][ i] = 0,dp[ i][ i+1 ] = 0 状态转移: 对于区间 [ i, j ],考虑以下几种情况: 情况1:直接移除整个区间(如果满足条件) 如果区间 [ i, j ] 内所有方块颜色相同且长度 ≥ 3,则: dp[ i][ j] = sum(costs[ i..j ]) 情况2:分割区间 对于所有可能的分割点 k (i ≤ k < j): dp[ i][ j] = max(dp[ i][ j], dp[ i][ k] + dp[ k+1][ j ]) 情况3:移除中间部分后两侧合并 如果 colors[ i] == colors[ j],考虑移除中间区间 [ l, r ] 后,两侧的 i 和 j 相邻: 对于区间 [ i, j ],如果存在某个分割方式,移除中间部分后剩下的两端可以继续合并得分 更精确的状态转移: dp[ i][ j ] = max( dp[ i][ j ], // 初始值 // 情况1:直接得分(如果满足条件) (如果区间内所有颜色相同且长度≥3 ? sum(costs[ i..j ]) : -∞), // 情况2:分割得分 max_ {i≤k<j} (dp[ i][ k] + dp[ k+1][ j ]), // 情况3:移除中间后合并得分 ... // 这里需要更复杂的处理 ) 优化状态设计: 为了处理情况3,我们需要更精细的状态定义: 定义 dp[ i][ j][ k] 表示在区间 [ i, j] 内,在区间左侧有 k 个与 colors[ i ] 同色的方块相连时能获得的最大得分 完整的状态转移方程: 令 dp[ i][ j][ k] 表示区间 [ i, j],且区间左侧有 k 个与 colors[ i ] 同色的方块 基础情况:当 i > j 时,dp[ i][ j][ k ] = 0 状态转移: 先移除第 i 个方块:dp[ i][ j][ k] = dp[ i+1][ j][ 0] + (如果 k ≥ 2 ? costs[ i ] : 0) 不移除第 i 个方块,寻找与 i 同色的位置 m: for m = i+1 to j: if colors[ i] == colors[ m ]: dp[ i][ j][ k] = max(dp[ i][ j][ k ], dp[ i+1][ m-1][ 0] + dp[ m][ j][ k+1 ]) 最终答案: dp[ 0][ n-1][ 0 ],其中 n 是方块数量 实现细节: 使用记忆化搜索或自底向上的DP 注意边界条件处理 时间复杂度:O(n³),空间复杂度:O(n²) 这个解法通过三维DP状态巧妙地处理了移除中间部分后两侧方块合并的情况,是这类"消消乐"类型问题的经典解法。