最长公共子序列的变种:带字符权重的最长公共子序列(进阶版:允许负权重)
字数 1088 2025-11-03 00:20:06

最长公共子序列的变种:带字符权重的最长公共子序列(进阶版:允许负权重)

题目描述:
给定两个字符串s和t,以及一个权重函数w,该函数为每个字符对(c1, c2)分配一个权重值。当c1和c2匹配时,我们可以获得相应的权重w(c1, c2)。与标准LCS不同,这里字符匹配可能产生正权重、负权重或零权重。我们的目标是找到一个s和t的公共子序列,使得该子序列中所有匹配字符对的权重之和最大。

解题过程:

  1. 问题分析:
  • 这是标准最长公共子序列(LCS)问题的加权变种
  • 关键区别:匹配字符可能带来正收益(正权重)或负收益(负权重)
  • 目标从"最大化子序列长度"变为"最大化权重和"
  1. 状态定义:
    定义dp[i][j]表示s的前i个字符和t的前j个字符形成的所有公共子序列的最大权重和。

  2. 状态转移方程:
    对于每个位置(i, j),我们有三种选择:

  • 不匹配s[i]:继承dp[i-1][j]
  • 不匹配t[j]:继承dp[i][j-1]
  • 匹配s[i]和t[j](当s[i] = t[j]时):dp[i-1][j-1] + w(s[i], t[j])

因此状态转移方程为:
dp[i][j] = max(
dp[i-1][j],
dp[i][j-1],
dp[i-1][j-1] + w(s[i], t[j]) (当s[i] = t[j]时)
)

  1. 边界条件:
  • dp[0][j] = 0(s为空字符串)
  • dp[i][0] = 0(t为空字符串)
  1. 算法步骤:
    步骤1:初始化dp表,大小为(m+1)×(n+1),m和n分别为s和t的长度
    步骤2:第一行和第一列初始化为0
    步骤3:按行遍历i从1到m,按列遍历j从1到n:

    • 计算option1 = dp[i-1][j]
    • 计算option2 = dp[i][j-1]
    • 如果s[i-1] == t[j-1],计算option3 = dp[i-1][j-1] + w(s[i-1], t[j-1])
    • dp[i][j] = max(option1, option2, option3)
      步骤4:最终结果在dp[m][n]
  2. 时间复杂度:O(m×n),空间复杂度:O(m×n)

  3. 关键理解点:

  • 负权重意味着某些匹配可能降低总权重,因此算法需要智能选择是否进行匹配
  • 当权重为负时,最优解可能选择跳过某些匹配
  • 标准LCS是本问题的特例(所有权重为1)

这个算法通过动态规划巧妙地处理了带权重的字符匹配,能够在正负权重混合的情况下找到最优的公共子序列。

最长公共子序列的变种:带字符权重的最长公共子序列(进阶版:允许负权重) 题目描述: 给定两个字符串s和t,以及一个权重函数w,该函数为每个字符对(c1, c2)分配一个权重值。当c1和c2匹配时,我们可以获得相应的权重w(c1, c2)。与标准LCS不同,这里字符匹配可能产生正权重、负权重或零权重。我们的目标是找到一个s和t的公共子序列,使得该子序列中所有匹配字符对的权重之和最大。 解题过程: 问题分析: 这是标准最长公共子序列(LCS)问题的加权变种 关键区别:匹配字符可能带来正收益(正权重)或负收益(负权重) 目标从"最大化子序列长度"变为"最大化权重和" 状态定义: 定义dp[ i][ j ]表示s的前i个字符和t的前j个字符形成的所有公共子序列的最大权重和。 状态转移方程: 对于每个位置(i, j),我们有三种选择: 不匹配s[ i]:继承dp[ i-1][ j ] 不匹配t[ j]:继承dp[ i][ j-1 ] 匹配s[ i]和t[ j](当s[ i] = t[ j]时):dp[ i-1][ j-1] + w(s[ i], t[ j ]) 因此状态转移方程为: dp[ i][ j ] = max( dp[ i-1][ j ], dp[ i][ j-1 ], dp[ i-1][ j-1] + w(s[ i], t[ j]) (当s[ i] = t[ j ]时) ) 边界条件: dp[ 0][ j ] = 0(s为空字符串) dp[ i][ 0 ] = 0(t为空字符串) 算法步骤: 步骤1:初始化dp表,大小为(m+1)×(n+1),m和n分别为s和t的长度 步骤2:第一行和第一列初始化为0 步骤3:按行遍历i从1到m,按列遍历j从1到n: 计算option1 = dp[ i-1][ j ] 计算option2 = dp[ i][ j-1 ] 如果s[ i-1] == t[ j-1],计算option3 = dp[ i-1][ j-1] + w(s[ i-1], t[ j-1 ]) dp[ i][ j ] = max(option1, option2, option3) 步骤4:最终结果在dp[ m][ n ] 时间复杂度:O(m×n),空间复杂度:O(m×n) 关键理解点: 负权重意味着某些匹配可能降低总权重,因此算法需要智能选择是否进行匹配 当权重为负时,最优解可能选择跳过某些匹配 标准LCS是本问题的特例(所有权重为1) 这个算法通过动态规划巧妙地处理了带权重的字符匹配,能够在正负权重混合的情况下找到最优的公共子序列。