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< ...
随机推荐
- web前端网页特效大全导航列表
CSS3和Html5 图表与图形 表单验证 导航菜单 table选项卡 视频播放器 日期和时间 返回顶部 图层代码 滚动代码 幻灯片 文字特效 图片放大镜 juqery焦点图 瀑布流 广告悬浮代码 在 ...
- iOS开发如何实现消息推送机制
一.关于推送通知 推送通知,也被叫做远程通知,是在iOS 3.0以后被引入的功能.是当程序没有启动或不在前台运行时,告诉用户有新消息的一种途径,是从外部服务器发送到应用程序上的.一般说来,当要显示消息 ...
- 使用开关、分段控件和web视图
#import "XViewController.h" @interface XViewController () @end @implementation XViewContro ...
- The Brain vs Deep Learning Part I: Computational Complexity — Or Why the Singularity Is Nowhere Near
The Brain vs Deep Learning Part I: Computational Complexity — Or Why the Singularity Is Nowhere Near ...
- windows_phone指定时间后执行函数
开发windows phone 应用程序时需要在一段指定的时间后执行某些函数,于是乎想到了通过DispatcherTimer类来实现,再在.Tick后面添加自己想要的事件 DispatcherTime ...
- Tomcat漏洞说明与安全加固
Tomcat是Apache软件基金会的一个免费的.开放源码的WEB应用服务器,可以运行在Linux和Windows等多个平台上,由于其性能稳定.扩展性好.免费等特点深受广大用户的喜爱.目前,互联网上绝 ...
- 百度Hi之CSRF蠕虫攻击
漏洞起因:百度是国内最大的中文搜索引擎.同时百度也提供了百度空间.百度贴吧等BLOG社区服务,拥有海量的用户群,号称全球最大中文社区. 80sec发现过百度产品一系列的安全漏洞,其中一些问题得到了有效 ...
- MYSQL注入天书之数据库增删改介绍
Background-4 增删改函数介绍 在对数据进行处理上,我们经常用到的是增删查改.接下来我们讲解一下mysql 的增删改.查就是我们上述总用到的select,这里就介绍了. 增加一行数据.Ins ...
- codeforces 463D Gargari and Permutations(dp)
题目 参考网上的代码的... //要找到所有序列中的最长的公共子序列, //定义状态dp[i]为在第一个序列中前i个数字中的最长公共子序列的长度, //状态转移方程为dp[i]=max(dp[i],d ...
- input:text 的value 和 attribute('value') 不是一回事
如题,input:text 当手工输入字符改变其值时,两者就不一样了. 要获得手工输入,不要用attribute('value'), 直接使用value: function getbyid(id){ ...