【问题标题】:Confused about two types of sub problems in dynamic programming对动态规划中的两类子问题感到困惑
【发布时间】:2021-08-27 05:23:01
【问题描述】:

首先我为我的英语不好而道歉。

最近我遇到了关于两种动态编程的一些令人困惑的事情。

在“最长公共子序列”问题中,如果 char 不相等,则我们取两个子问题之间的最大值。 另一方面“编辑距离”问题,如果字符不相等,那么我们至少需要三个子问题。

我的问题是为什么我们取三个子问题的最小值?
为什么我们不采取最少两个子问题,比如最长公共子序列?

【问题讨论】:

  • 动态编程只是构建解决方案的想法,以避免重新计算子问题以提高效率。这通常是通过缓存或创建子问题表。除此之外,这只是编程,您必须考虑细节才能理解它们为何如此——没有一般规则。

标签: c++ algorithm dynamic dynamic-programming


【解决方案1】:

选择的数量不同,因为这两个问题的性质不同。

对于Levenshtein distance(即您所指的编辑距离),三个选项对应于三个可能的操作。计算lev[i][j]时,对应子串a[1..i]b[1..j],如果是a[i] != b[j],那么三个选择分别是:

  • d[i][j-1],将a[1..i] 转换为b[1..j-1],然后插入 b[j]
  • d[i-1][j],将a[1..i-1] 转换为b[1..j],然后删除 a[i];
  • d[i-1][j-1],将a[1..i-1] 转换为b[1..j-1],然后替换 a[i]b[j]

如果您忽略第三个选项,那么您正在计算一个不同的编辑距离,一个只允许插入和删除的距离。这个编辑距离实际上与 LCS 问题紧密connected。具体来说,如果字符串的长度分别为mn,那么这个受限的编辑距离将是

D = m + n - 2 * LCS(a, b)

这种等式成立,因为为了仅使用插入和删除将a 转换为b,您必须:

  • 删除除 LCS 中的 a 的所有字符(因此 m - LCS(a,b) 操作);
  • 插入b 的所有字符,LCS 中的字符除外(因此n - LCS(a,b) 操作)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多