D 1. the maximum length of the subsequence after the string is deleted
1. Problem Description
Please delete several characters in the string "uxdqir1_jeuuryhkntuvpbyidyxqcxitpvsnskwjiijtz", and the remaining characters constitute a child sequence (that is, the sequence starts from 2nd characters, the ASCII code of each character is not less than the ASCII code of the previous character ). Calculates the longest subsequence without downgrading.
2. Key Points of Design
A string consisting of n characters is given. After several characters are deleted from the string, the remaining strings are made into non-subsequences. Set each character A (1), a (2 ),..., A (N), each character operation (delete or not delete) is a stage, a total of N stages.
(1) Establish a recurrence relationship
Set the B array. B (I) indicates the maximum length of the non-descending subsequence from the I character to the N character at the end of the sequence. I =,..., n. For all j> I, compare the maximum values of all B (j) When a (I) <= a (j). Obviously, B (I) adds 1 to the maximum value, add a (I.
There is a recurrence relationship:
B (I) = max (B (j) + 1 (a (I) <= a (J), 1 <= I <j <= N) boundary condition: B (n) = 1
(2) Calculate the optimal value through reverse push
B (n) = 1; <br/> for (I = n-1; I >=1; I --) {<br/> max = 0; <br/> for (j = I + 1; j <= N; j ++) <br/> if (a (I) <= a (j) & B (j)> MAX) <br/> max = B (j); <br/> B (I) = MAX + 1; // reverse B (I) <br/>}
Calculate B (n-1 ),..., B (1), compare N-1 1 values to the maximum Lmax value, that is, the length of the longest non-descending subsequence, that is, the optimal value.
(3) construct the optimal solution
Output B (I) is equal to Lmax, lmax-1 ,..., 1. A (I) is not smaller than the output item A (j). This is the longest non-downgrading subsequence.
3. Code Implementation
// Calculate the longest non-descending subsequence in the string <br/> # include <stdio. h> <br/> # include <stdlib. h> <br/> # include <time. h> </P> <p> int main (void) <br/> {<br/> int I, j, N, Max, Lmax, B [300]; <br/> char a [300]; </P> <p> // initialize the random number generator <br/> srand (time (0 )); </P> <p> printf ("input n (n <300):"); <br/> scanf ("% d", & N ); <br/> printf ("known string:/N"); <br/> for (I = 1; I <= N; I ++) {<br/> A [I] = rand () % 26 + 65; // generate and output n characters <br/> printf ("% C ", A [I]); <br/>}< br/> putchar ('/N'); </P> <p> B [N] = 1; lmax = 0; <br/> for (I = n-1; I> = 1; I --) {// returns the optimal Lmax value through reverse push. <br/> max = 0; <br/> for (j = I + 1; j <= N; j ++) <br/> if (a [I] <= A [J] & B [J]> MAX) <br/> max = B [J]; <br/> B [I] = MAX + 1; // returns B [I] <br/> If (B [I]> Lmax) <br/> Lmax = B [I]; // compare the maximum length of a non-descending sequence <br/>}</P> <p> printf ("the maximum length of a non-descending subsequence is % d/N ", lmax); <br/> printf ("the longest non-descending subsequence is:"); <br/> J = 0; A [0] = 0; <br/> for (I = 1; I <= N; I ++) <br/> If (B [I] = Lmax & A [J] <= A [I]) {<br/> printf ("% C ", A [I]); <br/> Lmax --; <br/> J = I; <br/>}< br/> putchar ('/N '); </P> <p> return 0; <br/>}
Ii. Longest Common subsequence
1. Question proposal
The subsequence of a sequence is obtained after several items are deleted from the sequence. For example, "bcba" is a common subsequence of "abcbdab" and "bdcaba. Given two sequences x = {x1, x2 ,..., xm} and Y = {y1, Y2 ,..., yn} to find the longest common subsequences of X and Y.
2. Key Points of Design
Longest Common subsequence problems have the optimal sub-structure nature and are solved using dynamic programming.
(1) Establish a recurrence relationship
Set sequence X = {x1, x2 ,..., xm} and Y = {y1, Y2 ,..., the longest common subsequence of yn} is Z = {Z1, Z2 ,..., ZK}, {x1, x2 ,..., xm} and {y1, Y2 ,..., yn} (I = 1 ,..., m; j = 1 ,..., n) The length of the longest common subsequence is C (I, j ).
If I = m + 1 or J = n + 1, it is an empty sequence and C (I, j) = 0 (boundary condition ).
If X (1) = y (1), then z (1) = x (1), C () = C) + 1 (where 1 is Z (1 ).
If X (1 )! = Y (1), then C () is greater than C () and C.
Generally, there is a recurrence relationship:
If X (I) = y (I), C (I, j) = C (I + 1, J + 1) + 1 (1 <= I <= m, 1 <= j <= N );
If X (I )! = Y (I), then C (I, j) = max (C (I + 1, J), C (I, j + 1 )).
Boundary Condition: C (I, j) = 0 (I = m + 1 or J = n + 1)
(2) Calculate the optimal value through reverse push
Based on the above recursive relationship, the optimal value of C () is calculated as follows:
For (I = 1; I <= m + 1; I ++) // returns the initial value <br/> C [I] [n + 1] = 0; <br/> for (j = 1; j <= N; j ++) <br/> C [M + 1] [J] = 0; </P> <p> for (I = m; I> = 1; I --) <br/> for (j = N; j> = 1; j --) {<br/> If (X [I] = Y [J]) <br/> C [I] [J] = C [I + 1] [J + 1] + 1; <br/> else if (C [I] [J + 1]> C [I + 1] [J]) <br/> C [I] [J] = C [I] [J + 1]; <br/> else <br/> C [I] [J] = C [I + 1] [J]; <br/>}</P> <p> // Output Optimal Solution <br/> printf ("Maximum length of common substring: % d ", c [1] [1]);
(3) construct the optimal value
To construct the optimal value, that is, to extract the longest common subsequence, set the array S (I, j). When X (I) = y (J), S (I, j) = 1; when X (I )! = Y (j) S (I, j) = 0.
Each item of the X sequence is compared with each item of the Y sequence one by one. The longest common subsequence is constructed according to the values of S (I, j) and C (I, j.
Compare the implementation of X (I) with Y (J), where I = 1, 2 ,..., m; j = 1, 2 ,..., n; variable t starts from 0. t = J + 1 when the longest common subsequence is determined. This prevents repeated items.
If S (I, j) = 1 and C (I, j) = C (1st), X (I) is the longest common subsequence;
Then, if S (I, j) = 1 and C (I, j) = C (2nd)-1, take the items of the longest common subsequence of X (I;
Generally, if S (I, j) = 1 and C (I, j) = C ()-2 (w starts from 0, for each item that determines the longest common subsequence, W is increased by 1) and W + 1 of the longest X (I) Common subsequence is obtained.
Construct the longest common subsequence description:
For (t = 0, W = 0, I = 1; I <= m; I ++) {<br/> for (j = T; j <= N; j ++) <br/> If (s [I] [J] = 1 & C [I] [J] = C [1] [1]-W) {<br/> printf ("% C", X [I]); <br/> W ++; <br/> T = J + 1; <br/> break; <br/>}< br/>}
(3) code implementation
// Obtain the longest public subsequence <br/> # include <stdio. h> <br/> # include <stdlib. h> <br/> # include <time. h> </P> <p> int main (void) <br/> {<br/> int I, j, T, M, N, W; <br/> int X [100], Y [100], s [100] [100], C [100] [100]; </P> <p> srand (Time (null); </P> <p> printf ("input M and N :"); <br/> scanf ("% d", & M, & N); <br/> printf ("known string X :"); <br/> for (I = 1; I <= m; I ++) {<br/> X [I] = rand () % 26 + 65; // generate and output M characters of x <br/> putchar (X [I]); <br/>}< br/> printf ("/n known string Y:"); <br/> for (I = 1; I <= N; I ++) {<br/> Y [I] = rand () % 26 + 65; // generate and output n characters of Y <br/> putchar (Y [I]); <br/>}</P> <p> // boundary value <br/> for (I = 1; I <= m + 1; I ++) <br/> C [I] [n + 1] = 0; <br/> for (j = 1; j <= n + 1; j ++) <br/> C [M + 1] [J] = 0; </P> <p> // recursive calculation of the optimal value <br/> for (I = m; i> = 1; I --) {<br/> for (j = N; j> = 1; j --) <br/> If (X [I] = Y [J]) {<br/> C [I] [J] = C [I + 1] [J + 1] + 1; <br/> S [I] [J] = 1; <br/>}< br/> else {<br/> S [I] [J] = 0; <br/> If (C [I] [J + 1]> C [I + 1] [J]) <br/> C [I] [J] = C [I] [J + 1]; <br/> else <br/> C [I] [J] = C [I + 1] [J]; <br/>}</P> <p> printf ("/N: % d ", c [1] [1]); // output optimal value <br/> printf ("/n Longest Common subsequence:"); <br/> T = 0; W = 0; <br/> for (I = 1; I <= m; I ++) {<br/> for (j = T; j <= N; j ++) <br/> If (s [I] [J] = 1 & C [I] [J] = C [1] [1]-W) {<br/> putchar (X [I]); <br/> W ++; <br/> T = J + 1; <br/> break; <br/>}< br/> putchar ('/N'); </P> <p> return 0; <br/>}