We have now started the subject of dynamic programming, and hung a teacher assignments
Longest common subsequence and the longest common strings are the classic title dp
Specific issues online has many variations, then let me introduce the most original question:
The problem is most typical of the longest common subsequence. It differs from the promoter sequence and the next point is substrings: sequence of characters in the original string is not necessarily continuous, but does not change the relative position of the letter, while the substring is a contiguous subset of the original string.
We can use dynamic programming methods to solve these two problems:
1. The longest common subsequence (LCS)
Provided X = x1x2 ... xm and Y = y1y2 ... yn are two sequences, Z = z1z2 ... zk is a longest common subsequence of the two sequences.
1. If xm = yn, then zk = xm = yn, and Zk-1 is an Xm-1, Yn-1 of a longest common subsequence;
2. If xm ≠ yn, then zk ≠ xm, meaning Z is Xm-1, a longest common subsequence of Y;
3. If xm ≠ yn, then zk ≠ yn, means that Z is X, Yn-1 of a longest common subsequence.
We use DP [i] [j] to represent a string of i bits before and second longest common subsequence first j bits in the string, we can easily find that when any two strings of a string the current length is zero, it is the length of the longest common subsequence is zero, so the first boundary dp array is initialized. Then we found that, if a [i] = b [j], dp [i] [j] = dp [i-1] [j-1] +1, obviously, than when the same pair of characters, the can the resulting equation of state transition. If a [i] ≠ b [j], dp [i] [j] = max (dp [i-1] [j], dp [i] [j-1]), the state transition equation is above 2,3 bar takes the maximum value obtained.
Look at the code below:
1 #include<bits/stdc++.h> 2 using namespace std; 3 int dp[2005][2005]; 4 int main() 5 { 6 char a[2005],b[2005]; 7 cin>>a>>b; 8 for(int i=0;i<=strlen(a);i++) 9 { 10 dp[i][0]=0; 11 } 12 for(int j=0;j<=strlen(b);j++) 13 { 14 dp[0][j]=0; 15 } 16 for(int i=1;i<=strlen(a);i++) 17 { 18 for(int j=1;j<=strlen(b);j++) 19 { 20 if(a[i-1]==b[j-1]) 21 { 22 dp[i][j]=dp[i-1][j-1]+1; 23 } 24 else 25 { 26 dp[i][j]=max(dp[i-1][j],dp[i][j-1]); 27 } 28 } 29 } 30 cout<<dp[strlen(a)][strlen(b)]<<endl; 31 return 0; 32 }
2. The longest common substring
This is the basic concept of the longest common substring, and sequences very much like, but the string is to require continuous. We use DP [i] [j] to represent a string of bits before i and j bits before the second sequence in the longest common substring, we can easily find that when any two strings of a string the current length is zero, it is the length of the longest common subsequence is zero, so the first boundary dp array is initialized. Then we found that, if a [i] = b [j ], dp [i] [j] = dp [i-1] [j-1] +1, obviously, than when the same pair of characters, the can the resulting equation of state transition. If a [i] ≠ b [j ], dp [i] [j] = 0, explanation has no continuous substring whether before, to this unequal position directly broken, so dp [i] [j] = 0;
The following is the longest common substring code:
#include<bits/stdc++.h> using namespace std; int dp[2005][2005]; int main() { char a[2005],b[2005]; cin>>a>>b; for(int i=0;i<=strlen(a);i++) { dp[i][0]=0; } for(int j=0;j<=strlen(b);j++) { dp[0][j]=0; } for(int i=1;i<=strlen(a);i++) { for(int j=1;j<=strlen(b);j++) { if(a[i-1]==b[j-1]) { dp[i][j]=dp[i-1][j-1]+1; } else { dp[i][j]=0; } } } cout<<dp[strlen(a)][strlen(b)]<<endl; return 0; }