Document directory
- Dynamic Planning involves four steps:
Dynamic Planning is not an algorithm, but a solution. Typical dynamic planning problems, such as the longest common subsequence (LCS) and longest monotonic subsequence (LIS.
Dynamic Planning involves four steps: 1. Determine whether the problem has an optimal sub-structure
Here we use LCS as an example, x = {x1, x2,..., Xi}; y = {y1, Y2,..., YJ }. Longest Common subsequence z = {Z1, Z2,..., ZK };
① If xi = YJ, then zk = xi = YJ, And the Zk-1 is a series of Xi-1 and Yj-1 LCs;
② If Xi is less than YJ, ZK is less than Xi; and ZK is the LCS of the sequential Xi-1 and YJ;
③ If xi = YJ, zk = YJ; and ZK is the sequence of Xi and Yj-1 LCs;
The establishment of the sub-structure can be proved by the reverse identification method.
2. a recursive Solution
Set C [I, j] to the length of LCS of Xi and YJ. When I = 0 or J = 0, C [I, j] = 0;
C [I, j] = 0 (I = 0 or J = 0)
C [I, j] = C [I-1, J-1] (I, j> 0; xi = YJ)
C [I, j] = max {C [I-1, J], C [I, J-1]} (I, j> 0; xi = YJ)
3. Calculate the length of LCS
C [I, j] is a recursive solution. How many different recursive solutions are there? O (M * n ). That is, there must be overlapping subproblems, rather than solving new problems every time. As for overlapping subproblems, we need to find them from the bottom up. You only need to index small-scale subproblems each time.
From the bottom up, solve C [I, j]. You also need to maintain B [I] [J] to simplify the structure of the optimal solution.
For example, the given two sequences are x = <A, B, C, B, D, a, B> and Y = <B, D, C, A, B, a>. The result 2 calculated by the algorithm lcs_length and LCS is shown in.
|
J |
|
0 |
|
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
I |
|
|
YJ |
|
B |
|
D |
|
C |
|
A |
|
B |
|
A |
|
|
|
Bytes |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Bytes |
0 |
XI |
│ |
|
|
0 |
|
0 |
|
0 |
|
0 |
|
0 |
|
0 |
│ |
|
|
│ |
|
|
Bytes |
|
Bytes |
|
Bytes |
|
|
|
|
|
|
│ |
1 |
A |
│ |
0 |
|
0 |
|
0 |
|
0 |
|
1 |
Bytes |
1 |
|
1 |
│ |
|
|
│ |
|
|
|
|
|
|
|
|
Bytes |
|
|
|
|
│ |
2 |
B |
│ |
0 |
|
1 |
Bytes |
1 |
Bytes |
1 |
|
1 |
|
2 |
Bytes |
2 |
│ |
|
|
│ |
|
|
Bytes |
|
Bytes |
|
|
|
|
|
Bytes |
|
Bytes |
│ |
3 |
C |
│ |
0 |
|
1 |
|
1 |
|
2 |
Bytes |
2 |
|
2 |
|
2 |
│ |
|
|
│ |
|
|
|
|
Bytes |
|
Bytes |
|
Bytes |
|
|
|
|
│ |
4 |
B |
│ |
0 |
|
1 |
|
1 |
|
2 |
|
2 |
|
3 |
Bytes |
3 |
│ |
|
|
│ |
|
|
Bytes |
|
|
|
Bytes |
|
Bytes |
|
Bytes |
|
Bytes |
│ |
5 |
D |
│ |
0 |
|
1 |
|
2 |
|
2 |
|
2 |
|
3 |
|
3 |
│ |
|
|
│ |
|
|
Bytes |
|
Bytes |
|
Bytes |
|
|
|
Bytes |
|
|
│ |
6 |
A |
│ |
0 |
|
1 |
|
2 |
|
2 |
|
3 |
|
3 |
|
4 |
│ |
|
|
│ |
|
|
|
|
Bytes |
|
Bytes |
|
Bytes |
|
|
|
Bytes |
│ |
7 |
B |
│ |
0 |
|
1 |
|
2 |
|
2 |
|
3 |
|
4 |
|
5 |
│ |
|
|
Bytes |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Bytes |
void LCS_LENGTH(char x[],char y[],const int len_x,const int len_y,int c[][ROW],int b[][ROW]){int i,j;for(i=1;i<len_x;i++){for(j=1;j<len_y;j++){if(x[i]==y[j]){c[i][j]=c[i-1][j-1]+1;b[i][j]=3;//3==""}elseif(c[i-1][j]>=c[i][j-1]){c[i][j]=c[i-1][j];b[i][j]=1;//1=="↑"}else{c[i][j]=c[i][j-1];b[i][j]=2;//2=="←"}}//for j}//for i}
4. Construct an LCs
Construct LCS according to table B [I] [J,
3 = "", indicating that X [I] is in ZK;
1 = "fill", indicating that X [I] is not in ZK, And to C [I] [J] = C [I-1] [J];
2 = "fill", indicating that X [I] is not in ZK, And to C [I] [J] = C [I] [J-1];
void PRINT_LCS(int b[][ROW],char x[],int m,int n){if(m==0||n==0)return;if(b[m][n]==3){PRINT_LCS(b,x,m-1,n-1);printf("%c\t",x[m]);}else if(b[m][n]==1){PRINT_LCS(b,x,m-1,n);}else{PRINT_LCS(b,x,m,n-1);}}