"""
最长公共子序列 (LCS) — 动态规划
比较两个序列的相似度
"""

def lcs_length(X, Y):
    """计算 LCS 长度并返回 DP 表"""
    m, n = len(X), len(Y)
    dp = [[0] * (n + 1) for _ in range(m + 1)]

    for i in range(1, m + 1):
        for j in range(1, n + 1):
            if X[i - 1] == Y[j - 1]:
                dp[i][j] = dp[i - 1][j - 1] + 1
            else:
                dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])

    return dp[m][n], dp

def lcs_backtrack(X, Y, dp):
    """回溯找出 LCS 序列"""
    i, j = len(X), len(Y)
    result = []

    while i > 0 and j > 0:
        if X[i - 1] == Y[j - 1]:
            result.append(X[i - 1])
            i -= 1
            j -= 1
        elif dp[i - 1][j] > dp[i][j - 1]:
            i -= 1
        else:
            j -= 1

    return ''.join(reversed(result))

if __name__ == "__main__":
    X = "ABCBDAB"
    Y = "BDCABB"

    length, dp_table = lcs_length(X, Y)
    lcs_str = lcs_backtrack(X, Y, dp_table)

    print(f"序列 X: {X}")
    print(f"序列 Y: {Y}")
    print(f"LCS 长度: {length}")
    print(f"LCS 序列: {lcs_str}")
