This problem is 51Nod set as the basic problem (this is a bit high AH), I feel that should be counted as a level or two-level topic, the main reason is not the dynamic programming of the state transfer equation, but need to understand the final backtracking algorithm.
Title: Find the longest subsequence of the two string, the requirements of the sub-sequence to satisfy the order of the characters and the letters in the two sequence must be the same, any output of a test instructions-compliant sub-sequence
The first is the state transition problem of the most basic and longest common sub-sequence :
Here the maxlen[i][j] array means to save the S1 's first I characters and the S2 's first J characters to match the state.
For example:maxlen[3][6] is the length of the longest common subsequence that is matched to the first 3 characters of S1 and the first 6 words of S2.
If we can understand this, then the key nature of the "no effect" of dynamic programming is understood, the key of dynamic programming is to find a reasonable optimal state so that it will not be affected in the subsequent state transfer, and its state is the sub-optimization problem of the optimal problem, Such a state allows us to step up to the parent optimization problem.
Maxlen[i-1][j-1] as a sub-problem of Maxlen[i][j]
There is a state transition equation when the S1-I character matches the J-character of S2:maxlen[i][j] = maxlen[i-1][j-1] + 1
Maxlen[i-1][j] and maxlen[i][j-1] are the best solutions to the previous state when I and J do not match.
i.e. there is a state transition equation when mismatch:maxlen[i][j] = max (maxlen[i-1][j], maxlen[i][]j-1)
A count code based on this state transfer equation is given below
1 //two find the longest string in a string2 //PS: Its characters exist in two strings and are in the same order-number of recorded characters3 4 #defineMax (x, y) (() > (y)? ( x):(y))5 6 intMaxlen[max][max];//S1 First I character and S2 first I character longest match7 8 intMatching (CharS1[],Chars2[])9 {Tenmemset (MaxLen,0,sizeof(MaxLen)); One intLen1 =strlen (S1); A intLen2 =strlen (S2); - for(i =1; I <= len1; i++) - for(j =1; J <= Len2; J + +) the if(S1[i-1] = = S2[j-1])//S1 front I and S2 J string tail character match -MAXLEN[I][J] = maxlen[i-1][j-1] +1; - Else //does not match -MAXLEN[I][J] = max (Maxlen[i][j-1], Maxlen[i-1][j]); + returnMaxlen[len1][len2]; -}e
Next is the most important backtracking algorithm for the problem, which is the key to the output sub-sequence:
To borrow a picture to describe the algorithm, the idea is as follows:
The method of finding the sub-sequence from a two-dimensional array marked with each state can be described as follows:
When the parent state Maxlen[i][j] and the closest two sub-states Maxlen[i-1][j] and maxlen[i][j-1] are not the same
Description at this time Maxlen[i][j] did the operation:maxlen[i][j] = maxlen[i-1][j-1] + 1
When the parent state Maxlen[i][j] is the same as any of the closest two child states
Description at this time Maxlen[i][j] did the operation:maxlen[i][j] = max (maxlen[i-1][j], maxlen[i][]j-1)
It is important to note that when the parent state and the nearest child state are the same , the two orientations of the translation are derived, thus deriving a collection of all the longest common subsequence .
Because the problem only needs to output any one, so specify a direction backtracking.
Therefore, combining the above two algorithms can draw the final algorithm of the problem:
//finding the longest common sub-sequence and losing it as a sub-sequence#include <cstdio>#include<cstring>#include<iostream>using namespacestd;#defineMAX 1001#defineMax (x, y) (() > (y)? ( x):(y))CharS1[max], S2[max];intMaxlen[max][max];CharAns[max];intMain () {intK =0; scanf ("%s%s", S1,S2); intLen1 =strlen (S1); intLen2 =strlen (S2); for(inti =1; I <= len1; i++) { for(intj =1; J <= Len2; J + +) { if(s1[i-1] = = s2[j-1]) Maxlen[i][j]= Maxlen[i-1][j-1] +1; ElseMAXLEN[I][J] = max (Maxlen[i][j-1], maxlen[i-1][j]); } } inti =len1; intj =Len2; while(i) {if(Maxlen[i][j] > Maxlen[i-1][j]) {if(Maxlen[i][j] > Maxlen[i][j-1]) Ans[maxlen[i][j]-1] = S1[i-1]; Elsei++;//Pan left Shiftj--;//Reduce one size} i--;//on Pan} printf ("%s\n", ans); return 0;}
ACM/ICPC the longest common subsequence count and its backtracking algorithm (51nod-1006 (longest common subsequence))