LCS 小结

转载链接:http://www.cnblogs.com/PJQOOO/p/3897745.html

第一步:先计算最长公共子序列的长度。

实现第一步:

    设一个C[i][j]: 保存Xi与Yj的LCS的长度。

    设X = { x1~xm },Y = { y1~yn }及它们的最长子序列Z = { z1~zk }则:

1、若 xm = yn , 则 zk = xm = yn,且Z[k-1] 是 X[m-1] 和 Y[n-1] 的最长公共子序列

2、若 xm != yn ,且 zk != xm , 则 Z 是 X[m-1] 和 Y 的最长公共子序列

3、若 xm != yn , 且 zk != yn , 则 Z 是 Y[n-1] 和 X 的最长公共子序列

子问题的递归结构:

当 i = 0 , j = 0 时 , c[i][j] = 0

当 i , j > 0 ; xi = yi 时 , c[i][j] = c[i-1][j-1] + 1

当 i , j > 0 ; xi != yi 时 , c[i][j] = max { c[i][j-1] , c[i-1][j] }

第二步:根据长度,然后通过回溯求出最长公共子序列。

实现代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <math.h>
 4 #include <limits.h> 
 5 #include <algorithm>
 6 #include <iostream>
 7 #include <ctype.h>
 8 #include <iomanip>
 9 #include <queue>
10 #include <map>
11 #include <stdlib.h>
12 using namespace std;
13 
14 char a[100],b[100],dp[100][100];
15 
16 int LCS(int n,int m){
17     int i,j;
18     int len=max(n,m);
19     for(i=0;i<=len;i++){
20         dp[i][0]=0;
21         dp[0][i]=0;
22     }
23     for(i=1;i<=n;i++){
24         for(j=1;j<=m;j++){
25             if(a[i-1]==b[j-1]){
26                 dp[i][j]=dp[i-1][j-1]+1;
27             }
28             else{
29                 dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
30             }
31         }
32     }
33     return dp[n][m];
34 }
35 
36 int main()
37 {
38     cin>>a;
39     cin>>b;
40     int n=strlen(a);
41     int m=strlen(b);
42     int k=LCS(n,m);
43     cout<<k<<endl;
44     int i=n-1,j=m-1,count=k;
45     while(count!=0){
46         if(a[i]==b[j]){
47             cout<<a[i];
48             i--;
49             j--;
50             count--;
51         }
52         else if(dp[i][j-1]>dp[i-1][j]){
53             j--;
54         }
55         else{
56             i--;
57         }
58     }
59     cout<<endl;
60 }

原文地址:https://www.cnblogs.com/wangmengmeng/p/4899036.html