http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1006
参考博客 :http://blog.csdn.net/yysdsyl/article/details/4226630
引进一个二维数组c[][],用c[i][j]记录X[i]与Y[j] 的LCS 的长度,b[i][j]记录c[i][j]是通过哪一个子问题的值求得的,以决定搜索的方向。
我们是自底向上进行递推计算,那么在计算c[i,j]之前,c[i-1][j-1],c[i-1][j]与c[i][j-1]均已计算出来。此时我们根据X[i] = Y[j]还是X[i] != Y[j],就可以计算出c[i][j]。
计算 LCS 复杂度 O(n*m).由于每次调用至少向上或向左(或向上向左同时)移动一步,故最多调用(m + n)次就会遇到i = 0或j = 0的情况,此时开始返回。返回时与递归调用时方向相反,步数相同,故打印输出算法时间复杂度为Θ(m + n)。
打印序列,非递归。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <set> 5 #include <queue> 6 #include <algorithm> 7 #define MAXN 1111 8 #define MAXM 222222 9 #define INF 1000000000 10 using namespace std; 11 12 char s[MAXN],t[MAXN],res[MAXN]; 13 int dp[MAXN][MAXN],flag[MAXN][MAXN]; 14 15 void LCS(int n,int m) 16 { 17 memset(dp,0,sizeof(dp)); 18 memset(flag,0,sizeof(flag)); 19 for(int i=1;i<=n;i++) 20 for(int j=1;j<=m;j++) 21 { 22 if(s[i-1]==t[j-1]) 23 { 24 dp[i][j]=dp[i-1][j-1]+1; 25 flag[i][j]=1; 26 } 27 else if(dp[i][j-1]>dp[i-1][j]) 28 { 29 dp[i][j]=dp[i][j-1]; 30 flag[i][j]=2; 31 } 32 else 33 { 34 dp[i][j]=dp[i-1][j]; 35 flag[i][j]=3; 36 } 37 } 38 //printf("%d\n",dp[n][m]); 39 } 40 41 void getLCS(int n,int m) 42 { 43 int k=0; 44 while(n>0&&m>0) 45 { 46 if(flag[n][m]==1) 47 { 48 res[k++]=s[n-1]; 49 n--; 50 m--; 51 } 52 else if(flag[n][m]==2) m--; 53 else if(flag[n][m]==3) n--; 54 } 55 for(int i=k-1;i>=0;i--) 56 { 57 printf("%c",res[i]); 58 } 59 printf("\n"); 60 } 61 62 int main() 63 { 64 //freopen("a.txt","r",stdin); 65 scanf("%s %s",s,t); 66 //printf("%s %s\n",s,t); 67 int l1=strlen(s),l2=strlen(t); 68 LCS(l1,l2); 69 /*for(int i=0;i<=l1;i++) 70 { 71 for(int j=0;j<=l2;j++) 72 printf("%d ",flag[i][j]); 73 printf("\n"); 74 } 75 printf("\n");*/ 76 getLCS(l1,l2); 77 return 0; 78 }