51 nod 1006 最长公共子序列Lcs
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的更多相关文章
- 51 Nod 1006 最长公共子序列(LCS & DP)
原题链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1006 题目分析: 首先先知道LCS问题,这有两种: Long ...
- 1006 最长公共子序列Lcs
1006 最长公共子序列Lcs 基准时间限制:1 秒 空间限制:131072 KB 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdks ...
- 51nod 1006 最长公共子序列Lcs 【LCS/打印path】
1006 最长公共子序列Lcs 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). ...
- 51nod 1006 最长公共子序列Lcs(经典动态规划)
传送门 Description 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是 ...
- 【51NOD】1006 最长公共子序列Lcs(动态规划)
给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是,abca也是,其中abca是这两个 ...
- 51Nod - 1006 最长公共子序列Lcs模板
给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是,abca也是,其中abca是这 ...
- 51Nod 1006 最长公共子序列Lcs问题 模板题
给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是,abca也是,其中abca是这两个 ...
- 51NOD 1006 最长公共子序列 Lcs 动态规划 DP 模板题 板子
给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最 ...
- 【51NOD-0】1006 最长公共子序列Lcs
[算法]经典DP [题解]经典lcs,输出路径可以记录上一个有效节点就是有点麻烦. 因为开始时写法不太明确,打印结果时初始循环地方搞错了,后来修正写法时忘了改过来,调了好久. #include< ...
随机推荐
- Maven搭建webService (三) 创建客户端---使用Apache CXF方式实现
package test; import net.cc.web.server.HelloWorld; import org.apache.cxf.jaxws.JaxWsProxyFactoryBean ...
- android控件---自定义带文本的ImageButton
由于SDK提供的ImageButton只能添加图片,不能添加文字:而Button控件添加的文字只能显示在图片内部:当我们需要添加文字在图片外部时就不能满足我们的需求了,顾只能自己写个自定义ImageB ...
- Leetcode#109 Convert Sorted List to Binary Search Tree
原题地址 跟Convert Sorted Array to Binary Search Tree(参见这篇文章)类似,只不过用list就不能随机访问了. 代码: TreeNode *buildBST( ...
- matrix_world_final_2013
A http://acm.hust.edu.cn/vjudge/contest/view.action?cid=98960#problem/A 题意:给一个正方形,四边上有A-Z带+-,如果是00就不 ...
- Win32 Plus Extra Height of Caption Bar
you set the size of the non-client area by handling the WM_NCCALCSIZE message. But don't do this unl ...
- Android Environment FAQ (Frequently Asked Question)
1.how to find out the Eclipse Version From Eclipse Menu Help ----> About Eclipse It displayed as ...
- Unity3D 错误,nativeVideoFrameCallback解决方法。
原地址:http://blog.csdn.net/alking_sun/article/details/23684733 Unity3D在打包安卓应用的时候,一打开游戏就闪退,接入LogCat之后发现 ...
- HDU4916 Count on the path(树dp??)
这道题的题意其实有点略晦涩,定义f(a,b)为 minimum of vertices not on the path between vertices a and b. 其实它加一个minimum ...
- ExtJs之Ext.isEmpty
<!DOCTYPE html> <html> <head> <title>ExtJs</title> <meta http-equiv ...
- ExtJS之Ext.getDom
<!DOCTYPE html> <html> <head> <title>ExtJs</title> <meta http-equiv ...