51nod 1006 最长公共子序列Lcs(dp+string,无标记数组实现)

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题
收藏
关注
取消关注
给出两个字符串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[i][j]表示字符串a的前i个字符与字符串b的前j个字符的最长公共子序列长度。
状态转移方程:dp[i][j]=a[i-1]==b[j-1]?dp[i-1][j-1]+1:max(dp[i-1][j],dp[i][j-1]);
边界条件dp[0][x]=dp[x][0]=0;

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 int dp[1005][1005]={0};
 5 string a,b;
 6 int la,lb;
 7 void lcs(int n,int m)
 8 {
 9     for(int i=1;i<=n;i++)
10         for(int j=1;j<=m;j++)
11         dp[i][j]=a[i-1]==b[j-1]?dp[i-1][j-1]+1:max(dp[i-1][j],dp[i][j-1]);
12 }
13 void output()
14 {
15     string ans;
16     int i=la,j=lb,len=dp[la][lb];
17     while(dp[i][j])
18     {
19         if(a[i-1]==b[j-1])
20             ans.push_back(a[i-1]),i--,j--;
21         else if(dp[i][j]==dp[i-1][j])
22             i--;
23         else if(dp[i][j]==dp[i][j-1])
24             j--;
25     }
26     for(int i=len-1;i>=0;i--)
27         cout<<ans[i];
28     cout<<endl;
29 }
30 int main()
31 {
32     ios::sync_with_stdio(false);
33     cin>>a>>b;
34     la=a.size(),lb=b.size();
35     lcs(la,lb);
36     output();
37     return 0;
38 }
View Code
原文地址:https://www.cnblogs.com/onlyli/p/7274055.html