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. 01.Redis安装

    1.安装Redis 1.下载.解压Redis [lizhiwei@localhost Redis]$ ll total 1248 -rwxrwxr-x. 1 lizhiwei lizhiwei 127 ...

  2. JS 学习笔记--4---运算符

    1.JS 中包含的运算符有:一元运算符.二元运算符.三元运算符.算术运算符.关系运算符.逻辑运算符.位运算符.赋值运算符.其他的运算符等. 2.表达式:简单来讲就是一句代码(分号隔开),解释器会把它翻 ...

  3. BZOJ 2820 YY的GCD

    AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=2820 有种方法是枚举质数然后用BZOJ2301来做但是超时了... 具体式子大概张这样: ...

  4. 【BZOJ】【2301】problem b

    莫比乌斯反演/容斥原理 Orz PoPoQQQ PoPoQQQ莫比乌斯函数讲义第一题. for(i=1;i<=n;i=last+1){ last=min(n/(n/i),m/(m/i)); …… ...

  5. matrix_last_acm_1

    password 123 A http://acm.hust.edu.cn/vjudge/contest/view.action?cid=96950#problem/A 题意:n个数初始ai,m次操作 ...

  6. fbx 模型转换 export

    最近在做自定义类型到fbx的转换 有关polygon的理解 vertex,normal,color等信息,是离散的放置的,对fbx里面的mesh加了控制点(vertex)信息之后, 需要再设置poly ...

  7. linux shell的输出效果修改方法(界面颜色)

    文本终端的颜色可以使用“ANSI非常规字符序列”来生成.举例: echo -e "\033[44;37;5m ME \033[0m COOL" 以上命令设置背景成为蓝色,前景白色, ...

  8. Xcode显示行号

  9. iOS应用间的跳转和传值

    在第一个应用程序中info.plist设置 URL Identifier: 该字符串是你自定义的 URL scheme 的名字 注意: URL Schemes 是一个数组,允许应用定义多个 URL s ...

  10. CPLD VS FPGA

    FPGA(Field-Programmable Gate Array),即现场可编程门阵列,它是在PAL.GAL.CPLD等可编程器件的基础上进一步发展的产物.它是作为专用集成电路(ASIC)领域中的 ...