LCS算法(Longest Common Sequence)

LCS算法

Longest Common Sequence

假设存在两个字符串序列 X 和 Y

X = { x 1 , x 2 , . . . , x n } X = \{x_1, x_2, ..., x_n\} X={x1,x2,...,xn}

Y = { y 1 , y 2 , . . . , y n } Y = \{y_1, y_2, ..., y_n\} Y={y1,y2,...,yn}

考虑两个序列最后一个元素是否相等,可以得到
L C S ( x n , y m ) = { L C S ( x n − 1 ,   y m − 1 ) + 1 , x n = y m m a x ( L C S ( x n − 1 , y m ) ,   L C S ( x n , y m − 1 ) ) , x n ! = y m LCS(x_n, y_m) = \begin{cases} LCS(x_{n-1},\ y_{m-1})+1 \quad , x_n = y_m\\ max(LCS(x_{n-1}, y_m),\ LCS(x_n, y_{m-1})) \quad ,x_n != y_m\\ \end{cases} LCS(xn,ym)={LCS(xn1, ym1)+1,xn=ymmax(LCS(xn1,ym), LCS(xn,ym1)),xn!=ym

同时考虑到当字串为0的时候就不存在相等元素,完善递推式
L C S ( x n , y m ) = { 0 , n = 0   o r   m = 0 L C S ( x n − 1 ,   y m − 1 ) + 1 , x n = y m m a x ( L C S ( x n − 1 , y m ) ,   L C S ( x n , y m − 1 ) ) , x n ! = y m LCS(x_n, y_m) = \begin{cases} 0 \quad ,n = 0 \ or \ m = 0 \\ LCS(x_{n-1},\ y_{m-1})+1 \quad , x_n = y_m\\ max(LCS(x_{n-1}, y_m),\ LCS(x_n, y_{m-1})) \quad ,x_n != y_m\\ \end{cases} LCS(xn,ym)=0,n=0 or m=0LCS(xn1, ym1)+1,xn=ymmax(LCS(xn1,ym), LCS(xn,ym1)),xn!=ym
递推式即为dp方程。

递推的过程是把一个大问题转化成子问题,同时我们在写dp程序的时候要明白一点 任何大问题转化成子问题的前提是子问题已经得解,从而反推到大问题解决!!!,所以实际上这个递推式转化成方程就是当任一字符串长度为0的时候,无元素相同,即为dp[0][0] = 0 dp[0][1] = 0dp[1][0] = 0 , 然后就可以通过递推式求其他情况的答案了。

// LCS典型题

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <string>

using namespace std;

const int N = 1e4 + 10;
int dp[N][N];

int main() {
    string a, b;
    getline(cin, a);
    getline(cin, b);

    for (int i = 1; i <= a.length(); i++) {
        for (int j = 1; j <= b.length(); j++) {
            if (a[i - 1] == b[j - 1]) {
                dp[i][j] = dp[i - 1][j - 1] + 1;
            } else {
                dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
            }
        }
    }
    
    cout << dp[a.length()][b.length()] << endl;
    return 0;
}

这里构造dp数组直接空出两行,表示任意一个序列长度为0的时候,无相同字符,对应位置数字为0

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值