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. 在win7/WINDOWS SERVER 2008 R2上安装 vmware POWERcli 6.5

    安装.NET Framework 4.6.2下载NDP462-KB3151800-x86-x64-AllOS-ENU.exe,安装安装PowerShell 4.0(5.0依赖4.0)下载Windows ...

  2. Linux下apache2及模块mod_deflate等安装和配置

    安装apache 1.wget http://archive.apache.org/dist/httpd/httpd-2.2.13.tar.gz 2.在安装目录 先让大家看看实际效果,请看下图10点中 ...

  3. javascript继承之组合继承(三)

    function Father(name) { this.name = name; } Father.prototype.say = function () { return this.name; } ...

  4. Lunce编程模型

    问题的场景: 解决方案:都是来自于科技论文 ============================================================================== ...

  5. Mongodb下载、安装、配置与使用

    记得在管理员模式下运行CMD,否则服务将启动失败 一.下载 官网下载地址:https://www.mongodb.com/download-center?jmp=nav#community 为了方便下 ...

  6. Java反射机制 —— 简单了解

    一.概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为jav ...

  7. ORACLE常用数值函数、转换函数、字符串函数介绍

    ORACLE常用数值函数.转换函数.字符串函数介绍. 数值函数: abs(m) m的绝对值 mod(m,n) m被n除后的余数 power(m,n) m的n次方 round(m[,n]) m四舍五入至 ...

  8. Configure First SpringMVC project in IntelliJ IDEA(fail)

    Configure First SpringMVC project in IntelliJ IDEA 13 The Mechanism of Spring MVC frameworks by Java ...

  9. 1_Utilities__deviceQuery + 1_Utilities__deviceQueryDrv + 1_Utilities__topologyQuery

    使用 Runtime API 和 Driver API 检测设备相关属性.并检测了设备之间的拓扑以及主机与设备之间的拓扑(是否支持跨设备原子操作). ▶ 源代码:Runtime API #includ ...

  10. HTML5 Canvas ( 绘制一片星空 )

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...