括号插入的最小成本问题
字数 992 2025-11-22 00:34:48
括号插入的最小成本问题
题目描述:
给定一个由"("、")"和"a"组成的字符串s,以及两个整数x和y。字符串中可能包含不匹配的括号。你可以执行两种操作:
- 在任意位置插入一个"(",成本为x
- 在任意位置插入一个")",成本为y
你的目标是通过最少的成本插入括号,使得整个字符串变成有效的括号序列。
解题过程:
步骤1:问题分析
- 有效的括号序列要求:每个左括号都有对应的右括号,且匹配顺序正确
- 我们需要在适当位置插入括号来修正不匹配的情况
- 插入左括号成本为x,插入右括号成本为y
步骤2:定义状态
设dp[i][j]表示将子串s[i...j]变成有效括号序列的最小成本。
步骤3:状态转移方程
情况1:如果s[i]是右括号")",我们有两种选择:
- 在i前面插入一个左括号与之匹配,成本为x + dp[i+1][j]
- 删除s[i](相当于插入右括号来匹配前面的左括号),成本为y + dp[i+1][j]
情况2:如果s[i]是左括号"(",我们需要找到与之匹配的右括号:
- 遍历所有可能的k(i < k ≤ j),如果s[k]是右括号")",那么:
dp[i][j] = min(dp[i][j], dp[i+1][k-1] + dp[k+1][j]) - 或者我们也可以选择不匹配,直接插入右括号:dp[i][j] = min(dp[i][j], y + dp[i+1][j])
情况3:对于任意区间[i,j],我们还可以考虑分割点:
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j]),其中i ≤ k < j
步骤4:边界条件
- 当i > j时,dp[i][j] = 0(空字符串已经是有效的)
- 当i = j时:
- 如果是"(",需要插入右括号,成本为y
- 如果是")",需要插入左括号,成本为x
- 如果是"a",需要插入一对括号,成本为min(x+y, 2x, 2y)中的最小值
步骤5:算法实现
我们使用自底向上的方法,按区间长度从小到大计算:
def minCostToMakeValid(s: str, x: int, y: int) -> int:
n = len(s)
dp = [[0] * (n + 1) for _ in range(n + 1)]
# 初始化长度为1的区间
for i in range(n):
if s[i] == '(':
dp[i][i] = y # 需要插入右括号
elif s[i] == ')':
dp[i][i] = x # 需要插入左括号
else: # 'a'
dp[i][i] = min(x + y, 2 * x, 2 * y)
# 按区间长度从小到大计算
for length in range(2, n + 1):
for i in range(n - length + 1):
j = i + length - 1
# 初始化为一个较大值
dp[i][j] = float('inf')
# 情况1:s[i]是右括号
if s[i] == ')':
dp[i][j] = min(dp[i][j], x + dp[i+1][j]) # 插入左括号
dp[i][j] = min(dp[i][j], y + dp[i+1][j]) # 插入右括号(删除当前)
# 情况2:s[i]是左括号
elif s[i] == '(':
dp[i][j] = min(dp[i][j], y + dp[i+1][j]) # 插入右括号
# 尝试匹配
for k in range(i + 1, j + 1):
if s[k] == ')':
dp[i][j] = min(dp[i][j], dp[i+1][k-1] + dp[k+1][j])
# 情况3:s[i]是字符'a'
else:
# 可以当作左括号、右括号,或者普通字符处理
dp[i][j] = min(dp[i][j], x + dp[i+1][j]) # 当作右括号,插入左括号
dp[i][j] = min(dp[i][j], y + dp[i+1][j]) # 当作左括号,插入右括号
# 尝试匹配
for k in range(i + 1, j + 1):
if s[k] == ')' or s[k] == 'a': # 'a'可以当作右括号
dp[i][j] = min(dp[i][j], dp[i+1][k-1] + dp[k+1][j])
# 情况4:分割区间
for k in range(i, j):
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j])
return dp[0][n-1]
步骤6:复杂度分析
- 时间复杂度:O(n³),需要三重循环
- 空间复杂度:O(n²),用于存储dp表
步骤7:优化考虑
可以通过预处理来优化匹配查找,将时间复杂度优化到O(n²),但基本的区间DP思路如上所述。