LCS: two sequences S1 and S2 are given. The largest public part of these two sequences S3 is the longest public subsequence of S1 and S2. PUBLIC PART
It must appear in the same order, but it does not need to be continuous.
Solution 1: before learning about dynamic planning, I can think of enumeration. Check all sub-sequences of S1 for the S2.
Select the longest common subsequence. For a sequence with a length of n, its subsequences have a total of 2 Nth Power. In this way, the time complexity of this algorithm is exponential.
This is obviously not suitable for long sequence solutions.
Solution 2: now that we have learned dynamic planning, let's see if we can solve this problem with the idea of dynamic planning. To use dynamic planning, there must be two
Component: There are optimal substructures and overlapping subproblems. To facilitate learning, let's first understand these two concepts.
If an optimal solution of a problem contains the optimal solution of a subproblem, the problem has an optimal sub-structure. When a recursive algorithm constantly calls the same problem
We say that this optimal problem involves overlapping subproblems.
Note: dynamic planning requires that its sub-problems be independent and overlap. This seems to be a conflict at the beginning, but it is not. But here we are talking about two different
Concept. Independent means that two subproblems with the same issue do not share resources. Overlapping subproblems refer to subproblems that can be identified as different subproblems.
Now.
Set X = <x1, x2... xm>, Y = <y1, y2... yn> is two sequences with Z = <z1, z2... zk> Any LCS of X and Y. We can conclude that:
1. If xm = yn, then zk = xm = yn and Z (k-1) is an LCS of X (S-1) and Y (n-1;
2. If xm! = Yn, so zk! = Xm contains an LCS of X (S-1) and Y;
3. If xm! = Yn, so zk! = Yn contains Z as an LCS of X and Y (n-1.
Note: The above Z (k-1) represents the sequence Z <z1, z2. .. zn>, where n = K-1. The other X () and Y () are the same.
It is easy to prove that the above three points are true. For details, see Introduction to algorithms. Therefore, LCS has the optimal sub-structure. We can also see from the above that the weight of the LCS Problem
The nature of stacked subproblems. Therefore, we can use dynamic planning to solve the LCS problem. The recursive formula can be obtained from the optimal sub-structure of the LCS problem:
Let's take a look at the implementation code:
# Include <iostream> # include <cstring> using namespace std; int c [100] [100]; // c [I] [j] indicates the LCSint B of the first I element of sequence S1 and the first j element of sequence S2. [100] [100]; // The optimal solution void LCS_Length (char x [], char y []); void Print_LCS (char x [], int I, int j); int main () {char X [100], Y [100]; while (cin> X> Y) {LCS_Length (X, Y); Print_LCS (X, strlen (X ), strlen (Y); cout <endl;} return 0;} void LCS_Length (char x [], char y []) {int m = strlen (x ); int n = strlen (y); for (int I = 0; I <= m; I ++) c [I] [0] = 0; for (int I = 0; I <= n; I ++) c [0] [I] = 0; for (int I = 0; I <m; I ++) {for (int j = 0; j <n; j ++) {if (x [I] = y [j]) {c [I + 1] [j + 1] = c [I] [j] + 1; B [I + 1] [j + 1] = 0 ;} else if (c [I] [j + 1]> = c [I + 1] [j]) {c [I + 1] [j + 1] = c [I] [j + 1]; B [I + 1] [j + 1] = 1 ;} else {c [I + 1] [j + 1] = c [I + 1] [j]; B [I + 1] [j + 1] = 2 ;}}} void Print_LCS (char x [], int I, int j) {if (I = 0) | (j = 0) return; if (B [I] [j] = 0) {Print_LCS (x, i-1, j-1); cout <x [I-1] <'';} else if (B [I] [j] = 1) print_LCS (x, I-1, j); elsePrint_LCS (x, I, j-1 );}
The book provides a method to save space, that is, do not use arrays B to directly judge. Because c [I] [j] depends only on c [I-1] [I-1], c [I-1] [j], c [I] [J-1].
In this case, you only need to modify the Print_LCS function.