LCS-2#4260

LCS-2 (Editorial)

The task of this problem is to find the longest common subsequence (LCS) of two strings and print it.

Construct an array , where dp[i][j] represents the length of the LCS of the substrings x_{[1 \ldots i]} and y_{[1 \ldots j]}. The value will correspond to the length of the LCS of the original strings (|x| = n, |y| = m).

After computing the array, reconstruct the LCS by performing a reverse traversal of the matrix from cell to . At each position , we follow the next steps:

The resulting string will contain the longest common subsequence of and .

Example

Let us examine the process of finding the longest common subsequence (LCS) for two strings provided in the example.

The search for the LCS starts at position (i, j) = (6, 7).

y[6] \ne x[7]: move to any adjacent cell with the maximum value, for example, .

y[5] \ne x[7]: move to .

y[5] = x[6] = '': make a diagonal move and include the character '' in the LCS.

Algorithm implementation

Declare the input strings and . To find their LCS, we'll use the array.

#define MAX 1001
int dp[MAX][MAX];
string x, y, res;

Read the input strings. Add a space in front of each of them so that indexing starts from .

cin >> x; n = x.length(); x = " " + x;
cin >> y; m = y.length(); y = " " + y;

Compute the LCS.

for (i = 1; i <= n; i++)
for (j = 1; j <= m; j++)
  if (x[i] == y[j])
    dp[i][j] = dp[i - 1][j - 1] + 1;
  else
    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);

Build the LCS in the string .

i = n; j = m;
while (i >= 1 && j >= 1)
  if (x[i] == y[j])
  {
    res = res + x[i];
    i--; j--;
  }
  else
  {
    if (dp[i - 1][j] > dp[i][j - 1])
      i--;
    else
      j--;
  }

Invert and print the resulting string.

reverse(res.begin(), res.end());
cout << res << endl;