Longest common subsequence (LCS)
Longest Common Subsequence (LCS)
Problem statement
Two sequences and are given. It is required to find the length of the longest common subsequence.
Longest Common Subsequence (LCS)
Two sequences and are given. It is required to find the length of the longest common subsequence.
For example, the longest common subsequence of and is .
Let denote the solution for the prefix of of length and the prefix of of length . I.e., the length of the longest common subsequence of and .
The base cases are:
Now let us try to find transitions for the general case . Let us analyze the transitions:
Therefore, we have the formula:
Let us, for each non-base state, remember the best transition. I.e., we know that has three different transitions:
Let us create another array and store in which transition is best for . For example, if then we have .
After that, we can now reconstruct the answer. Initialize and do the following until and .
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
dp[i][j] = 0;
dp[i][j] = max(dp[i][j], dp[i - 1][j]);
dp[i][j] = max(dp[i][j], dp[i][j - 1]);
if (a[i] == b[j]) {
dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + 1);
}
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
dp[i][j] = -1;
if (dp[i - 1][j] > dp[i][j]) {
dp[i][j] = dp[i - 1][j];
p[i][j] = 1;
}
if (dp[i][j - 1] > dp[i][j]) {
dp[i][j] = dp[i][j - 1];
p[i][j] = 2;
}
if (a[i] == b[j] && dp[i - 1][j - 1] + 1 > dp[i][j]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
p[i][j] = 3;
}
}
}
vector<int> res;
int x = n, y = m;
while (x > 0 && y > 0) {
if (p[x][y] == 3) {
res.push_back(a[x]);
x -= 1;
y -= 1;
} else if (p[x][y] == 2) {
y -= 1;
} else { // p[x][y] == 1
x -= 1;
}
}
reverse(res.begin(), res.end());