LCS问题

本身是很简单的一个贪心+DP,做作业想熟悉下md,就用md写了。然后心想都用md写了就上传一下做个记录吧。

1. 状态转移方程

为方便说明,并不完全按照教材来定义

1. 定义

下标从\(1\)开始
\(n\)表示序列\(X\)的长度
\(m\)表示序列\(Y\)的长度
\(dp[i][j]\)表示\(X[1..i]\)\(Y[1..j]\)的最长公共子序列(该定义也和教材不同),因此\(dp[n][m]\)就是最终答案。
\(a\leftarrow b\)表示\(b\)\(a\)产生影响,例如\(a\leftarrow b_1\)\(a\leftarrow b_2\)表示\(a=max(b_1, b_2)\)

2. 说明

首先,\(dp\)数组的设计是常见想法,例如在最大子数组和问题中定义的\(dp[i]\)即为以第i个元素结尾的子数组的最大和。本问题由于有两个序列,因此定义二维\(dp\)数组即可。

接下来考虑转移状态,考虑如何推出\(dp[i][j]\):

\(X[i]=Y[j]\)时,\(dp[i-1][j-1]\)代表的序列(注意,\(dp\)的值保存的是长度)可以直接加上\(X[i]/Y[j]\),即\(dp[i][j]\leftarrow dp[i-1][j-1]+1\)。并且此时一定不比\(dp[i-1][j]\)\(dp[i][j-1]\)要差(因为\(dp[i-1][j-1]\)\(dp[i-1][j]\)\(dp[i][j-1]\)最多也就\(+1\))。因此此时可以直接令\(dp[i][j]=dp[i-1][j-1]+1\)

\(X[i]\neq Y[j]\)时,在\(X[1..i]\)\(Y[1..j]\)中,选出的最长公共子序列的末尾一定不可能是由\(X[i]/Y[j]\)得到的,换句话说,\(X[i]和Y[j]\)一定有一个没法算进\(dp[i][j]\)。此时考虑\(X[i]\)不选的情况,则\(dp[i][j]\leftarrow dp[i-1][j]\);考虑\(Y[j]\)不选的情况,则\(dp[i][j]\leftarrow dp[i][j-1]\)

综上,当\(X[i]=Y[j]\)时,\(dp[i][j]=dp[i-1][j-1]+1\);当\(X[i]\neq Y[j]\)时,\(dp[i][j]=max(dp[i-1][j], dp[i][j-1])\)

2. 填充\(dp\)数组

C T C A C A G G
A 0 0 0 1 1 1 1 1
T 0 1 1 1 1 1 1 1
T 0 1 1 1 1 1 1 1
C 1 1 2 2 2 2 2 2
G 1 1 2 2 2 2 3 3
A 1 1 2 3 3 3 3 3
G 1 1 2 3 3 3 4 4

3. 最长公共子序列

最长公共子序列长度为4,其中两个为:
\(TCGG\)
\(TCAG\)

posted @ 2025-05-28 20:18  TimeLimit  阅读(22)  评论(0)    收藏  举报