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)。

打印序列,非递归。

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#define MAXN 1111
#define MAXM 222222
#define INF 1000000000
using namespace std; char s[MAXN],t[MAXN],res[MAXN];
int dp[MAXN][MAXN],flag[MAXN][MAXN]; void LCS(int n,int m)
{
memset(dp,,sizeof(dp));
memset(flag,,sizeof(flag));
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
if(s[i-]==t[j-])
{
dp[i][j]=dp[i-][j-]+;
flag[i][j]=;
}
else if(dp[i][j-]>dp[i-][j])
{
dp[i][j]=dp[i][j-];
flag[i][j]=;
}
else
{
dp[i][j]=dp[i-][j];
flag[i][j]=;
}
}
//printf("%d\n",dp[n][m]);
} void getLCS(int n,int m)
{
int k=;
while(n>&&m>)
{
if(flag[n][m]==)
{
res[k++]=s[n-];
n--;
m--;
}
else if(flag[n][m]==) m--;
else if(flag[n][m]==) n--;
}
for(int i=k-;i>=;i--)
{
printf("%c",res[i]);
}
printf("\n");
} int main()
{
//freopen("a.txt","r",stdin);
scanf("%s %s",s,t);
//printf("%s %s\n",s,t);
int l1=strlen(s),l2=strlen(t);
LCS(l1,l2);
/*for(int i=0;i<=l1;i++)
{
for(int j=0;j<=l2;j++)
printf("%d ",flag[i][j]);
printf("\n");
}
printf("\n");*/
getLCS(l1,l2);
return ;
}

递归

 #include<cstdio>
#include<cstring>
const int maxn=;
int dp[maxn][maxn],flag[maxn][maxn];
int n,m;
char s[maxn],t[maxn]; void LCS(int n,int m)
{
memset(dp,,sizeof(dp));
memset(flag,,sizeof(flag));
for(int i=;i<n;i++)
for(int j=;j<m;j++)
{
if(s[i]==t[j])
{
dp[i+][j+]=dp[i][j]+;
flag[i+][j+]=;
}
else if(dp[i+][j]>dp[i][j+])
{
dp[i+][j+]=dp[i+][j];
flag[i+][j+]=;
}
else
{
dp[i+][j+]=dp[i][j+];
flag[i+][j+]=;
}
}
// printf("%d\n",dp[n][m]);
} void printLCS(int n,int m)
{
if(n==||m==) return; if(flag[n][m]==)
{
printLCS(n-,m-);
printf("%c",s[n-]);
}
else if(flag[n][m]==) printLCS(n,m-);
else printLCS(n-,m);
}
int main()
{
//freopen("a.txt","r",stdin);
scanf("%s %s",s,t);
int l1=strlen(s),l2=strlen(t);
LCS(l1,l2);
printLCS(l1,l2);
return ;
}

下面这种是比较简洁的。去掉了标记数组。

 #include<string>
#include<iostream>
using namespace std;
const int maxn = ; int dp[maxn][maxn]={};
string a,b; void LCS(int n,int m)
{
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
if(a[i-]==b[j-]) dp[i][j]=dp[i-][j-]+;
else dp[i][j]=max(dp[i][j-],dp[i-][j]);
} int main()
{
cin>>a>>b;
int l1=a.size(),l2=b.size();
LCS(l1,l2);
int len=dp[l1][l2];
string ans;
int i=l1,j=l2;
while(dp[i][j])
{
if(dp[i][j]==dp[i-][j]) i--;
else if(dp[i][j]==dp[i][j-]) j--;
else ans.push_back(a[i-]),i--,j--;
}
for(int i=len-;i>=;i--)
cout<<ans[i];
return ;
}

51 nod 1006 最长公共子序列Lcs的更多相关文章

  1. 51 Nod 1006 最长公共子序列(LCS & DP)

    原题链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1006 题目分析: 首先先知道LCS问题,这有两种: Long ...

  2. 1006 最长公共子序列Lcs

    1006 最长公共子序列Lcs 基准时间限制:1 秒 空间限制:131072 KB 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdks ...

  3. 51nod 1006 最长公共子序列Lcs 【LCS/打印path】

    1006 最长公共子序列Lcs  基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). ...

  4. 51nod 1006 最长公共子序列Lcs(经典动态规划)

    传送门 Description 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的).   比如两个串为:   abcicba abdkscab   ab是两个串的子序列,abc也是 ...

  5. 【51NOD】1006 最长公共子序列Lcs(动态规划)

    给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为:   abcicba abdkscab   ab是两个串的子序列,abc也是,abca也是,其中abca是这两个 ...

  6. 51Nod - 1006 最长公共子序列Lcs模板

    给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的).   比如两个串为:   abcicba abdkscab   ab是两个串的子序列,abc也是,abca也是,其中abca是这 ...

  7. 51Nod 1006 最长公共子序列Lcs问题 模板题

    给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为:   abcicba abdkscab   ab是两个串的子序列,abc也是,abca也是,其中abca是这两个 ...

  8. 51NOD 1006 最长公共子序列 Lcs 动态规划 DP 模板题 板子

    给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最 ...

  9. 【51NOD-0】1006 最长公共子序列Lcs

    [算法]经典DP [题解]经典lcs,输出路径可以记录上一个有效节点就是有点麻烦. 因为开始时写法不太明确,打印结果时初始循环地方搞错了,后来修正写法时忘了改过来,调了好久. #include< ...

随机推荐

  1. IIS和MVC

    现象:MVC项目部署到IIS(7.5)后,浏览时只显示文件目录,不是网站 解决办法 1.服务器安装程序对应的Framework版本 2.服务器安装程序对应的MVC版本 3.安装CGI和ISAPI扩展: ...

  2. 【CentOS】安装配置vncserver

    参考资料: http://my.oschina.net/yankunren/blog/70042 安装过程 (1).检查vncserver是否已经安装 [root@Nginx canyouNgx]# ...

  3. hdu 3046 Pleasant sheep and big big wolf 最小割

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3046 In ZJNU, there is a well-known prairie. And it a ...

  4. 集合类 Collection

    1.Collection接口有两个子接口: List:保存元素顺序的线性表,允许有重复元素. Set:不记录元素的保存顺序,不允许有重复元素.数学中的集合 Collection接口中的方法如下: Co ...

  5. Cortex-M3/4的Hard Fault调试方法

    1 Cortex-M3/4的Fault简介 Cortex-M3/4的Fault异常是由于非法的存储器访问(比如访问0地址.写只读存储位置等)和非法的程序行为(比如除以0等)等造成的.常见的4种异常及产 ...

  6. ES6中的高阶函数:如同 a => b => c 一样简单

    作者:Sequoia McDowell 2016年01月16日 ES6来啦!随着越来越多的代码库和思潮引领者开始在他们的代码中使用ES6,以往被认为是"仅需了解"的ES6特性变成了 ...

  7. DevExpress GridView 自定义搜索按钮改为中文内容

    首先将 GridControl 控件的搜索功能显示出来. http://www.cnblogs.com/DeepLearing/p/3887601.html 显示效果如下: 可以通过 GridLoca ...

  8. AutoCompleteTextView的应用

    现在我们上网几乎都会用百度或者谷歌搜索信息,当我们在输入框里输入一两个字后,就会自动提示我们想要的信息,这种效果在Android 里是如何实现的呢? 事实上,Android 的AutoComplete ...

  9. Es使用。

    http://jingyan.baidu.com/article/3052f5a1e8a06397f31f8699.html --------------------------- http://el ...

  10. ***PHP preg_match正则表达式的使用

    第一,让我们看看两个特别的字符:‘^’和‘$’他们是分别用来匹配字符串的开始和结束,以下分别举例说明 : "^The": 匹配以 "The"开头的字符串; &q ...