最长公共子序列 LCS 递归 dp 51Nod 1006

给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的)。
 
比如两个串为:
 
abcicba
abdkscab
 
ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列。
Input
第1行:字符串A
第2行:字符串B
(A,B的长度 <= 1000)
Output
输出最长的子序列,如果有多个,随意输出1个。
Input示例
abcicba
abdkscab
Output示例
abca

先用dp 找到最大值,且标记路径,然后递归 从终点走到起点,然后输出。
 1 #include <iostream>
 2 using namespace std;
 3 #include<string.h>
 4 #include<set>
 5 #include<stdio.h>
 6 #include<math.h>
 7 #include<queue>
 8 #include<map>
 9 #include<algorithm>
10 #include<cstdio>
11 #include<cmath>
12 #include<cstring>
13 #include <cstdio>
14 #include <cstdlib>
15 #include<stack>
16 char  a[1010];
17 char  b[1010];
18 int dp[1010][1010];
19 int  c[1010][1010];
20 void dfs(int i,int j)
21 {
22     if(!i||!j)
23         return ;
24     if(c[i][j]==0)
25     {
26         dfs(i-1,j-1);
27         cout<<a[i];
28     }
29     else if(c[i][j]==1)
30     {
31         dfs(i-1,j);
32     }
33     else
34     {
35         dfs(i,j-1);
36     }
37 }
38 int main()
39 {
40     memset(dp,0,sizeof(dp));
41     cin>>(a+1)>>(b+1);
42     int lena=strlen(a+1);
43     int lenb=strlen(b+1);
44     memset(c,0,sizeof(c));
45     for(int i=1;i<=lena;i++)
46     {
47         for(int j=1;j<=lenb;j++)
48         {
49             if(a[i]==b[j])
50                 dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
51             else if(dp[i-1][j]>dp[i][j-1])
52             {
53                 dp[i][j]=dp[i-1][j];
54                 c[i][j]=1;
55             }
56             else
57             {
58                 dp[i][j]=dp[i][j-1];
59                 c[i][j]=2;
60             }
61         }
62     }
63     dfs(lena,lenb);
64     return 0;
65 }
View Code

 

posted @ 2017-09-09 19:34  小小超plus  阅读(304)  评论(0编辑  收藏  举报