LCS--Longest Common Subsequence,即最长公共子序列,一般使用DP来解。

常规方法:

dp[i][j]表示字符串s1前i个字符组成的字符串与s2前j个字符组成的字符串的LCS的长度,则当s1[i-1]==s2[j-1]时,dp[i][j]=dp[i-1][j-1]+1,否则dp[i][j]=max(dp[i-1][j],dp[i][j-1])。

最终的dp[len1][len2]即最终答案。代码如下:

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; char s1[],s2[];
int len1,len2;
int dp[][]; int main(){
while(~scanf("%s%s",s1,s2)){
len1=strlen(s1),len2=strlen(s2);
for(int i=;i<=len1;++i) dp[i][]=;
for(int i=;i<=len2;++i) dp[][i]=;
for(int i=;i<=len1;++i)
for(int j=;j<=len2;++j)
if(s1[i-]==s2[j-])
dp[i][j]=dp[i-][j-]+;
else
dp[i][j]=max(dp[i-][j],dp[i][j-]);
printf("%d\n",dp[len1][len2]);
}
return ;
}

如果需要打印路径:

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; char s1[],s2[];
int len1,len2;
int dp[][],path[][]; void print(int p1,int p2){
if(p1==||p2==) return;
else{
if(path[p1][p2]==) print(p1-,p2-),printf("%c",s1[p1-]);
else if(path[p1][p2]==) print(p1-,p2);
else print(p1,p2-);
}
} int main(){
while(~scanf("%s%s",s1,s2)){
len1=strlen(s1),len2=strlen(s2);
for(int i=;i<=len1;++i) dp[i][]=;
for(int i=;i<=len2;++i) dp[][i]=;
for(int i=;i<=len1;++i)
for(int j=;j<=len2;++j)
if(s1[i-]==s2[j-])
dp[i][j]=dp[i-][j-]+,path[i][j]=;
else if(dp[i-][j]>=dp[i][j-])
dp[i][j]=dp[i-][j],path[i][j]=;
else
dp[i][j]=dp[i][j-],path[i][j]=;
printf("%d\n",dp[len1][len2]);
print(len1,len2);
printf("\n");
}
return ;
}

空间优化:

如果只需要求LCS的长度,实际上只需要dp[n]就行了,应用滚动数组。因为dp[i][j]由dp[i-1][j-1],dp[i-1][j],dp[i][j-1],用dp[j]表示dp[i][j],则更新dp[j]时用pre存储dp[i-1][j-1],此时的dp[j-1]表示dp[i][j-1],此时的dp[j]表示dp[i-1][j],这样就大大优化了空间,详见代码:

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; char s1[],s2[];
int len1,len2,pre,tmp;
int dp[]; int main(){
while(~scanf("%s%s",s1,s2)){
len1=strlen(s1),len2=strlen(s2);
memset(dp,,sizeof(dp));
for(int i=;i<=len1;++i){
pre=;
for(int j=;j<=len2;++j){
tmp=dp[j];
if(s1[i-]==s2[j-])
dp[j]=pre+;
else
dp[j]=max(dp[j-],dp[j]);
pre=tmp;
}
}
printf("%d\n",dp[len2]);
}
return ;
}

时间优化:

据说可以将LCS转换为LIS解法,从而使时间复杂度降为O(nlogn),但似乎在某些特殊情况复杂度比常规做法更麻烦,不被建议使用。等以后接触时再更......

DP解LCS问题模板及其优化的更多相关文章

  1. 数据结构图文解析之:哈夫曼树与哈夫曼编码详解及C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  2. 数据结构图文解析之:队列详解与C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  3. 数据结构图文解析之:AVL树详解及C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  4. 数据结构图文解析之:二叉堆详解及C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  5. python操作三大主流数据库(5)python操作mysql⑤使用Jinja2模板提取优化页面展示

    python操作mysql⑤使用Jinja2模板提取优化页面展示 在templates目录下的index.html.cat.html等页面有一些共同的元素,代码比较冗余可以使用模板提取公共代码,在各网 ...

  6. 【题解】ARC101F Robots and Exits(DP转格路+树状数组优化DP)

    [题解]ARC101F Robots and Exits(DP转格路+树状数组优化DP) 先删去所有只能进入一个洞的机器人,这对答案没有贡献 考虑一个机器人只能进入两个洞,且真正的限制条件是操作的前缀 ...

  7. 39.Python模板结构优化-引入模板include标签、模板继承使用详解

    在进行模板的构造时,不免有些模板的部分样式会相同,如果每一个模板都是重写代码的话,不仅在做的时候麻烦,而且在后期的维护上,也是相当的麻烦.所以我们可以将模板结构进行优化,优化可以通过:引入模板:模板继 ...

  8. 高斯—若尔当(约当)消元法解异或方程组+bitset优化模板

    高斯消元法是将矩阵化为上三角矩阵 高斯—若尔当消元法是 选定主元后,将主元化为1,枚举除主元之外的所有行进行消元 即将矩阵化为对角矩阵,这样不用回代 bitset<N>a[N]; int ...

  9. 动态规划——最长公共子序列LCS及模板

    摘自 https://www.cnblogs.com/hapjin/p/5572483.html 这位大佬写的对理解DP也很有帮助,我就直接摘抄过来了,代码部分来自我做过的题 一,问题描述 给定两个字 ...

随机推荐

  1. bzoj3871: [Neerc2013 C]Cactus Automorphisms || 3899: 仙人掌树的同构

    Description 给定一个N,N<=50 000个节点的仙人掌,其是指每条边最多在一个环中的无向图,求仙人掌有多少种自同构.自同构是指得是图的顶点集合V到V的变换M, 以P1^a1*P2^ ...

  2. springMVC学习(10)-上传图片

    需求:在修改商品页面,添加上传商品图片功能. SpringMVC中对多部件类型解析: 1)springmvc中配置: <!-- 文件上传 --> <bean id="mul ...

  3. 杂项:Juice UI

    ylbtech-杂项:Juice UI Juice UI是开源的 WebForms 控件集,是一个功能强大的框架,它可以给ASP .NET开发人员带来丰富的.可以作为易于使用的控件的jQuery UI ...

  4. 1110 Complete Binary Tree (25 分)

    1110 Complete Binary Tree (25 分) Given a tree, you are supposed to tell if it is a complete binary t ...

  5. shell脚本判断语句和循环语句

    if判断语句 exit跳出判读语句 不加exit的结果 read -n(不换行) 判断是否输入的是数字 read age[[ $age =~ ^[0-9]+$ ]]if [ $? -ne 0 ]; t ...

  6. 第8章 信号(6)_贯穿案例2:mini shell(3)

    4. 贯穿案例2:mini shell(3) (1)之前存在问题 ①刚运行时,mshell作为前台进程.运行的其他命令会被加入新的进程组,并且调用tcsetpgrp将这个进程组设置为前台进程组,因此m ...

  7. CSS 背景background实例

    css背景background用于设置html标签元素的背景颜色.背景图片已经其他背景属性.本文章向码农介绍CSS 背景background使用方法和基本的使用实例.需要的码农可以参考一下. 一.Cs ...

  8. 解决npm下载包失败的问题

    在我朝,用npm直接从官方的镜像下载包,经常会出现网络超时下载失败的问题,具体原因大家都懂,我就不说了. 不过,这些都无法阻挡我们对知识的渴望,一下提供几种我在工作中的解决办法,希望能帮助你. 1.安 ...

  9. 学习MongoDB 二:MongoDB添加、删除、修改

    一.简介 MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSQL数据库产品中最热门的一种.数据被分组存储在数据集中,被称为一个集合(Collenction)和对于存储在MongoDB ...

  10. 随着firefox的迭代更新:FireBug不能用了?使用火狐Try Xpath插件替代Firebug和Firepath

    本篇文章讲解如何在火狐中安装和使用Try Xpath(插件替代Firebug和Firepath). 在火狐中安装Try Xpath 1. 打开火狐浏览器 FireFox57以上的版本 2. 在火狐菜单 ...