区间动态规划例题:最长括号匹配子序列问题(带权值版本)
字数 1134 2025-11-12 09:42:09

区间动态规划例题:最长括号匹配子序列问题(带权值版本)

题目描述:
给定一个由 '(' 和 ')' 组成的字符串 s,以及一个权值数组 w,其中 w[i] 表示第 i 个字符的权值。请找出最长的有效括号子序列,并计算其权值和。有效括号子序列定义为:空字符串是有效的;如果 A 是有效的,那么 (A) 也是有效的;如果 A 和 B 是有效的,那么 AB 也是有效的。

解题过程:

  1. 问题分析
    我们需要在字符串 s 中找到一个子序列(不一定连续),这个子序列是有效的括号序列,并且我们希望这个子序列尽可能长。当有多个最长有效括号子序列时,我们需要找出权值和最大的那个。

  2. 状态定义
    定义 dp[i][j] 表示在子串 s[i:j+1] 中,最长有效括号子序列的长度和对应的最大权值和。我们可以用一个元组 (length, weight) 来表示。

  3. 状态转移方程
    考虑区间 [i, j] 的最优解:

情况1:不包含字符 s[i]
dp[i][j] = dp[i+1][j]

情况2:包含字符 s[i],且 s[i] 是 '('
我们需要在区间 [i+1, j] 中找到一个 ')' 与它匹配
对于所有 k ∈ [i+1, j],如果 s[k] == ')',那么:
候选解 = (dp[i+1][k-1].length + dp[k+1][j].length + 2,
dp[i+1][k-1].weight + dp[k+1][j].weight + w[i] + w[k])

情况3:直接合并两个子区间
对于所有 k ∈ [i, j-1]:
候选解 = (dp[i][k].length + dp[k+1][j].length, dp[i][k].weight + dp[k+1][j].weight)

  1. 初始化
    对于长度为1的区间,dp[i][i] = (0, 0)(单个字符无法形成有效括号对)
    对于空区间,dp[i][i-1] = (0, 0)

  2. 计算顺序
    按照区间长度从小到大计算:

  • 先计算长度为2的区间
  • 然后计算长度为3的区间
  • 依此类推,直到计算整个字符串
  1. 最终结果
    dp[0][n-1] 就是整个字符串的最长有效括号子序列的长度和最大权值和。

举例说明:
假设 s = "()()", w = [1, 2, 3, 4]
最长有效括号子序列可以是 "()()"(长度4,权值和1+2+3+4=10)
或者 "(())"(长度4,权值和1+4+2+3=10)

通过这个动态规划过程,我们可以在 O(n³) 的时间复杂度内解决问题,其中 n 是字符串长度。

区间动态规划例题:最长括号匹配子序列问题(带权值版本) 题目描述: 给定一个由 '(' 和 ')' 组成的字符串 s,以及一个权值数组 w,其中 w[ i ] 表示第 i 个字符的权值。请找出最长的有效括号子序列,并计算其权值和。有效括号子序列定义为:空字符串是有效的;如果 A 是有效的,那么 (A) 也是有效的;如果 A 和 B 是有效的,那么 AB 也是有效的。 解题过程: 问题分析 我们需要在字符串 s 中找到一个子序列(不一定连续),这个子序列是有效的括号序列,并且我们希望这个子序列尽可能长。当有多个最长有效括号子序列时,我们需要找出权值和最大的那个。 状态定义 定义 dp[ i][ j] 表示在子串 s[ i:j+1 ] 中,最长有效括号子序列的长度和对应的最大权值和。我们可以用一个元组 (length, weight) 来表示。 状态转移方程 考虑区间 [ i, j ] 的最优解: 情况1:不包含字符 s[ i ] dp[ i][ j] = dp[ i+1][ j ] 情况2:包含字符 s[ i],且 s[ i ] 是 '(' 我们需要在区间 [ i+1, j ] 中找到一个 ')' 与它匹配 对于所有 k ∈ [ i+1, j],如果 s[ k ] == ')',那么: 候选解 = (dp[ i+1][ k-1].length + dp[ k+1][ j ].length + 2, dp[ i+1][ k-1].weight + dp[ k+1][ j].weight + w[ i] + w[ k ]) 情况3:直接合并两个子区间 对于所有 k ∈ [ i, j-1 ]: 候选解 = (dp[ i][ k].length + dp[ k+1][ j].length, dp[ i][ k].weight + dp[ k+1][ j ].weight) 初始化 对于长度为1的区间,dp[ i][ i ] = (0, 0)(单个字符无法形成有效括号对) 对于空区间,dp[ i][ i-1 ] = (0, 0) 计算顺序 按照区间长度从小到大计算: 先计算长度为2的区间 然后计算长度为3的区间 依此类推,直到计算整个字符串 最终结果 dp[ 0][ n-1 ] 就是整个字符串的最长有效括号子序列的长度和最大权值和。 举例说明: 假设 s = "()()", w = [ 1, 2, 3, 4 ] 最长有效括号子序列可以是 "()()"(长度4,权值和1+2+3+4=10) 或者 "(())"(长度4,权值和1+4+2+3=10) 通过这个动态规划过程,我们可以在 O(n³) 的时间复杂度内解决问题,其中 n 是字符串长度。