括号匹配的最大得分问题(带符号权重版本)
字数 2151 2025-11-08 20:56:04

括号匹配的最大得分问题(带符号权重版本)

题目描述
给定一个由字符 '('')' 和数字('0''9')组成的字符串 s。字符串中每对匹配的括号 "()" 有一个得分,得分规则如下:

  • 如果一对括号内部没有其他括号,且内部是一个数字字符,则该括号对的得分为该数字的值。例如,"(3)" 的得分为 3。
  • 如果一对括号内部包含其他括号或数字,则该括号对的得分为内部所有括号对得分的和乘以 2。例如,"((3))" 的得分为 2 * 3 = 6"(3(4))" 的得分为 2 * (3 + 4) = 14
  • 数字字符可以独立存在(不在括号内),此时数字的值为其本身(例如 "3" 的得分为 3)。
  • 括号必须正确匹配,输入保证有效性。

要求计算整个字符串的总得分。

示例
输入:s = "(3(4))"
输出:14
解释:外层括号包含内层 (4)(得分为 4)和数字 3,总和为 3 + 4 = 7,外层括号得分乘以 2 得 14

解题过程

  1. 问题分析

    • 括号匹配问题通常用栈或区间动态规划(DP)处理。本题中括号的得分依赖于内部结构,适合用区间 DP。
    • 定义 dp[i][j] 表示子串 s[i:j+1] 的总得分。
    • 关键点:当 s[i]s[j] 是一对匹配括号时,需要根据内部内容计算得分;否则需要分割子串计算和。
  2. 状态转移方程

    • 情况1s[i] 是数字且不在括号内(即 s[i] 不是 '('')'),则 dp[i][j] 可拆分为数字得分加上剩余部分得分:
      dp[i][j] = int(s[i]) + dp[i+1][j]
    • 情况2s[i]'('s[j] 是匹配的 ')',则计算内部得分:
      1. 如果内部是数字(如 "(3)"),得分为数字值。
      2. 如果内部包含其他括号,得分为内部总得分乘以 2。
        但内部可能包含多个独立部分(如 "(3(4))" 中的 3(4)),需遍历内部所有可能的分割点 k,求和内部得分。
        转移方程:
        dp[i][j] = 2 * sum(dp[i+1][k] + dp[k+1][j-1]),其中 k 为内部分割点。
        实际上,更简单的方式:直接计算内部整个区间 [i+1, j-1] 的得分,然后乘以 2。
        修正:内部可能包含并列的括号或数字,因此需要找到所有并列部分求和。例如 "(3(4))" 中内部是 "3(4)",包含数字 3 和括号 (4),需分别计算得分再求和。
        因此,正确做法是:
      • 先计算内部区间 [i+1, j-1] 的总得分(通过 DP 分割求和)。
      • 若内部全为数字,得分就是数字和;否则得分乘以 2。
        但规则中,只要括号内部有内容(无论是否嵌套),得分都乘以 2。因此统一处理:
        dp[i][j] = 2 * dp[i+1][j-1]
    • 情况3:子串可分割为两部分,得分相加:
      dp[i][j] = max(dp[i][k] + dp[k+1][j]),对 i ≤ k < j 遍历。
  3. 详细步骤

    • 步骤1:初始化 DP 表,dp[i][i] 表示单个字符的得分:
      • s[i] 是数字,dp[i][i] = int(s[i])
      • s[i] 是括号,dp[i][i] = 0(括号不能单独得分)。
    • 步骤2:按区间长度 len 从小到大的顺序计算 dp[i][j]
      1. s[i] 是数字,尝试拆分为数字 + 剩余:dp[i][j] = int(s[i]) + dp[i+1][j]
      2. s[i] == '('s[j] == ')',且内部 [i+1, j-1] 是有效括号序列,则:
        dp[i][j] = max(dp[i][j], 2 * dp[i+1][j-1])
      3. 遍历所有分割点 k,更新:
        dp[i][j] = max(dp[i][j], dp[i][k] + dp[k+1][j])
    • 步骤3:最终答案为 dp[0][n-1],其中 n 是字符串长度。
  4. 示例演算s = "(3(4))",长度为 6)

    • 初始化:dp[1][1] = 3(字符 '3'),dp[3][3] = 4(字符 '4')。
    • 计算区间 [3,5](子串 "(4)"):
      • dp[3][5] = 2 * dp[4][4] = 2 * 4 = 8
    • 计算区间 [1,5](子串 "3(4)"):
      • 分割:dp[1][5] = dp[1][1] + dp[2][5] = 3 + 8 = 11
    • 计算整个区间 [0,5](子串 "(3(4))"):
      • dp[0][5] = 2 * dp[1][5] = 2 * 11 = 14
        结果正确。
  5. 复杂度分析

    • 时间复杂度:O(n³),需要三重循环(区间长度、起点、分割点)。
    • 空间复杂度:O(n²),存储 DP 表。

通过以上步骤,可处理任意符合规则的括号字符串得分计算。

括号匹配的最大得分问题(带符号权重版本) 题目描述 给定一个由字符 '(' 、 ')' 和数字( '0' 到 '9' )组成的字符串 s 。字符串中每对匹配的括号 "()" 有一个得分,得分规则如下: 如果一对括号内部 没有其他括号 ,且内部是一个数字字符,则该括号对的得分为该数字的值。例如, "(3)" 的得分为 3。 如果一对括号内部包含其他括号或数字,则该括号对的得分为内部所有括号对得分的和乘以 2。例如, "((3))" 的得分为 2 * 3 = 6 ; "(3(4))" 的得分为 2 * (3 + 4) = 14 。 数字字符可以独立存在(不在括号内),此时数字的值为其本身(例如 "3" 的得分为 3)。 括号必须正确匹配,输入保证有效性。 要求计算整个字符串的总得分。 示例 输入: s = "(3(4))" 输出: 14 解释:外层括号包含内层 (4) (得分为 4)和数字 3 ,总和为 3 + 4 = 7 ,外层括号得分乘以 2 得 14 。 解题过程 问题分析 括号匹配问题通常用栈或区间动态规划(DP)处理。本题中括号的得分依赖于内部结构,适合用区间 DP。 定义 dp[i][j] 表示子串 s[i:j+1] 的总得分。 关键点:当 s[i] 和 s[j] 是一对匹配括号时,需要根据内部内容计算得分;否则需要分割子串计算和。 状态转移方程 情况1 : s[i] 是数字且不在括号内(即 s[i] 不是 '(' 或 ')' ),则 dp[i][j] 可拆分为数字得分加上剩余部分得分: dp[i][j] = int(s[i]) + dp[i+1][j] 。 情况2 : s[i] 是 '(' 且 s[j] 是匹配的 ')' ,则计算内部得分: 如果内部是数字(如 "(3)" ),得分为数字值。 如果内部包含其他括号,得分为内部总得分乘以 2。 但内部可能包含多个独立部分(如 "(3(4))" 中的 3 和 (4) ),需遍历内部所有可能的分割点 k ,求和内部得分。 转移方程: dp[i][j] = 2 * sum(dp[i+1][k] + dp[k+1][j-1]) ,其中 k 为内部分割点。 实际上,更简单的方式:直接计算内部整个区间 [i+1, j-1] 的得分,然后乘以 2。 修正 :内部可能包含并列的括号或数字,因此需要找到所有并列部分求和。例如 "(3(4))" 中内部是 "3(4)" ,包含数字 3 和括号 (4) ,需分别计算得分再求和。 因此,正确做法是: 先计算内部区间 [i+1, j-1] 的总得分(通过 DP 分割求和)。 若内部全为数字,得分就是数字和;否则得分乘以 2。 但规则中,只要括号内部有内容(无论是否嵌套),得分都乘以 2。因此统一处理: dp[i][j] = 2 * dp[i+1][j-1] 。 情况3 :子串可分割为两部分,得分相加: dp[i][j] = max(dp[i][k] + dp[k+1][j]) ,对 i ≤ k < j 遍历。 详细步骤 步骤1 :初始化 DP 表, dp[i][i] 表示单个字符的得分: 若 s[i] 是数字, dp[i][i] = int(s[i]) ; 若 s[i] 是括号, dp[i][i] = 0 (括号不能单独得分)。 步骤2 :按区间长度 len 从小到大的顺序计算 dp[i][j] : 若 s[i] 是数字,尝试拆分为数字 + 剩余: dp[i][j] = int(s[i]) + dp[i+1][j] 。 若 s[i] == '(' 且 s[j] == ')' ,且内部 [i+1, j-1] 是有效括号序列,则: dp[i][j] = max(dp[i][j], 2 * dp[i+1][j-1]) 。 遍历所有分割点 k ,更新: dp[i][j] = max(dp[i][j], dp[i][k] + dp[k+1][j]) 。 步骤3 :最终答案为 dp[0][n-1] ,其中 n 是字符串长度。 示例演算 ( s = "(3(4))" ,长度为 6) 初始化: dp[1][1] = 3 (字符 '3' ), dp[3][3] = 4 (字符 '4' )。 计算区间 [3,5] (子串 "(4)" ): dp[3][5] = 2 * dp[4][4] = 2 * 4 = 8 。 计算区间 [1,5] (子串 "3(4)" ): 分割: dp[1][5] = dp[1][1] + dp[2][5] = 3 + 8 = 11 。 计算整个区间 [0,5] (子串 "(3(4))" ): dp[0][5] = 2 * dp[1][5] = 2 * 11 = 14 。 结果正确。 复杂度分析 时间复杂度:O(n³),需要三重循环(区间长度、起点、分割点)。 空间复杂度:O(n²),存储 DP 表。 通过以上步骤,可处理任意符合规则的括号字符串得分计算。