LIS、LCS、LCIS

  • 最长上升子序列LIS
  • 最长公共子序列LCS
  • 最长公共上升子序列LCIS

最长上升子序列LIS

题目链接:AcWing895. 最长上升子序列

这里只说明 O ( n 2 ) O(n^2) O(n2)的解法, O ( n l o g n ) O(nlogn) O(nlogn)解法之前的博客有介绍
O ( n 2 ) O(n^2) O(n2)的解法较为容易理解

状态表示:
这里状态用一维表示,dp[i]表示以b[i]作为结尾的最长子序列的长度状态转移:
遍历b[i]前的所有元素,找出最长的以b[i]结尾的最长子序列长度
for(int j=0;j<i;j++)if(b[j]<b[i]) dp[i]=max(dp[i],dp[j]+1)

代码如下

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1010;
int b[N];
int dp[N];
int main(){int n,res=0;cin>>n;for(int i=1;i<=n;i++) scanf("%d",&b[i]);b[0]=-0x3f3f3f3f;for(int i=1;i<=n;i++){for(int j=0;j<i;j++)if(b[i]>b[j]) dp[i]=max(dp[i],dp[j]+1);res=max(res,dp[i]);}cout<<res;return 0;
}

最长公共子序列LCS

题目链接:AcWing897. 最长公共子序列

状态表示:
状态用二维表示,dp[i][j]表示A[1~i],B[1~j]的最长公共子序列状态转移:
if(A[i]==B[j]) dp[i][j]=dp[i-1][j-1]+1;//最长公共子序列增长一位
else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);//从两种情况中选择长的一种传递

代码如下

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1010;
int dp[N][N];//dp[i][j]表示A[1~i]与B[1~j]最长公共子序列
char A[N],B[N];
int main(){int n,m;cin>>n>>m;cin>>A+1>>B+1;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)if(A[i]==B[j]) dp[i][j]=dp[i-1][j-1]+1;else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);cout<<dp[n][m];return 0;
}

最长公共上升子序列LCIS

AcWing272. 最长公共上升子序列

这里我们考虑将上面的LIS和LCS结合

状态表示:
状态用二维来表示
dp[i][j]表示A[1~i]与B[1~j]且以B[j],结尾的最长公共上升子序列长度状态转移:if(A[i]!=B[j]) dp[i][j]=dp[i-1][j];else {int t=0;for(int k=1;k<j;k++)if(B[k]<B[j]) t=max(t,dp[i][k]);dp[i][j]=t+1;
}
当A[i]!=B[j]时,状态从dp[i-1][j]转移来
当A[i]==B[j]时,我们要考虑将B[j]前面求出的最长公共上升子序列中的哪个子序列之后,所以需要遍历前面所有的子序列(A[i]与B[1~k],k<j匹配的子序列)

代码如下

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=3010;
int A[N],B[N];
int dp[N][N];//dp[i][j]表示A[1~i]与B[1~j]且以B[j],结尾的最长公共上升子序列int main(){int n;cin>>n;for(int i=1;i<=n;i++) scanf("%d",&A[i]);for(int i=1;i<=n;i++) scanf("%d",&B[i]);for(int i=1;i<=n;i++){for(int j=1;j<=n;j++)if(A[i]!=B[j]) dp[i][j]=dp[i-1][j];else {int t=0;for(int k=1;k<j;k++)if(B[k]<B[j]) t=max(t,dp[i][k]);dp[i][j]=t+1;}}int res=0;for(int i=1;i<=n;i++)res=max(res,dp[n][i]);cout<<res;return 0;
}

我们可以发现这里的时间复杂度为 O ( n 3 ) O(n^3) O(n3),能处理的数据范围很小
我们可以对上面的代码进行优化,
其中

if(B[k]<B[j]) t=max(t,dp[i][k]);
此处的B[j]==A[i],所以可以写成
if(B[k]<A[i]) t=max(t,dp[i][k]);
我们要找到最大的B[k],可以提前将max(B[k])求出来

将下面代码优化

    for(int i=1;i<=n;i++){for(int j=1;j<=n;j++)if(A[i]!=B[j]) dp[i][j]=dp[i-1][j];else {int t=0;for(int k=1;k<j;k++)if(B[k]<B[j]) t=max(t,dp[i][k]);dp[i][j]=t+1;}}

可以在遍历B[1~j]中求出B[k]<A[i]时的最大的dp[i][k]

    for(int i=1;i<=n;i++){int t=0;for(int j=1;j<=n;j++){if(A[i]!=B[j]) dp[i][j]=dp[i-1][j];else dp[i][j]=t+1;if(A[i]>B[j]) t=max(t,dp[i][j]);}}

代码如下

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=3010;
int A[N],B[N];
int dp[N][N];//dp[i][j]表示A[1~i]与B[1~j]且以B[j],结尾的最长公共上升子序列int main(){int n;cin>>n;for(int i=1;i<=n;i++) scanf("%d",&A[i]);for(int i=1;i<=n;i++) scanf("%d",&B[i]);for(int i=1;i<=n;i++){int t=0;for(int j=1;j<=n;j++){if(A[i]!=B[j]) dp[i][j]=dp[i-1][j];else dp[i][j]=t+1;if(A[i]>B[j]) t=max(t,dp[i][j]);}}int res=0;for(int i=1;i<=n;i++)res=max(res,dp[n][i]);cout<<res;return 0;
}

最长上升子序列、最长公共子序列、最长公共上升子序列(LIS、LCS、LCIS)相关推荐

  1. 最长公共子序列|最长公共子串|最长重复子串|最长不重复子串|最长回文子串|最长递增子序列|最大子数组和...

    最长公共子序列|最长公共子串|最长重复子串|最长不重复子串|最长回文子串|最长递增子序列|最大子数组和 文章作者:Yx.Ac   文章来源:勇幸|Thinking (http://www.ahathi ...

  2. 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串 (转)...

    作者:寒小阳 时间:2013年9月. 出处:http://blog.csdn.net/han_xiaoyang/article/details/11969497. 声明:版权所有,转载请注明出处,谢谢 ...

  3. 【To Understand】动态规划:求最长公共子串/最长公共子序列

    动态规划:求最长公共子串/最长公共子序列 本博客转载自:https://blog.csdn.net/u013074465/article/details/45392687 该博客中详细讲解了求最长公共 ...

  4. 最长公共子序列变种——带权的最长公共子序列

    1 问题描述 在最长公共子序列及Python实现点击打开链接中讲到了最长公共子序列问题描述及实现过程.现在如果在求最长公共子序列的基础上,对每一个字符加上权重,如有两个序列a={'a','b','c' ...

  5. 最长公共子序列 【DP】+【最长公共子序列】

    最长公共子序列 时间限制: 3000 ms  |            内存限制: 65535 KB 难度: 3 描述 咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列. tip ...

  6. 求最长公共子序列python_用Python计算最长公共子序列和最长公共子串

    1. 什么是最长公共子序列?什么是最长公共子串? 1.1. 最长公共子序列(Longest-Common-Subsequences,LCS) 最长公共子序列(Longest-Common-Subseq ...

  7. 最长公共子序列动态规划c语言,动态规划----最长公共子序列(C++实现)

    最长公共子序列 题目描述:给定两个字符串s1 s2 - sn和t1 t2 - tm .求出这两个字符串的最长公共子序列的长度.字符串s1 s2 - sn的子序列指可以表示为 - { i1 < i ...

  8. java最长回文子序列_算法--字符串:最长回文子序列

    转自:labuladong公众号 子序列问题是常见的算法问题,而且并不好解决. 首先,子序列问题本身就相对子串.子数组更困难一些,因为前者是不连续的序列,而后两者是连续的,就算穷举都不容易,更别说求解 ...

  9. c语言动态规划公共字符串,最长公共子串 C语言 动态规划

    给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列. 一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何 ...

  10. C语言输出长方柱的体积,需要求3个长方柱的体积,请编写一个基于对象的程序。数据成员包括length(长)、width(宽)、 height(高)。要求用成员函数实现以下功能...

    需要求3个长方柱的体积,请编写一个基于对象的程序.数据成员包括length(长).width(宽). height(高).要求用成员函数实现以下功能: (1) 由键盘分别输入3个长方柱的长.宽.高: ...

最新文章

  1. 简直骚操作,ThreadLocal还能当缓存用
  2. OpenCV中LUT函数的使用
  3. ASP.NET Core中HTTP管道和中间件的二三事
  4. Android开发中的单元测试
  5. LVS-DR工作原理图文详解(转载)
  6. 拨号720错误解决记.txt
  7. 浅谈5类过零检测电路
  8. python图像增强算法_python 图像增强算法实现详解
  9. 手机图标ui设计尺寸:ui设计app图标尺寸规范
  10. 力扣143 链表重排
  11. 二维码内置图片,并且把二维码放在图片指定位置上,画字,设置字本地样式,二维码批量生成
  12. 期望值最大化算法 EM_GMM 估计高斯混合模型
  13. verilogVGA显示太极图案
  14. Macbook双系统 10.11及Ubuntu
  15. Linux常见配置文件
  16. 体系结构 | 五段流水线 | 流水线技术
  17. WampServer修改MySQL密码
  18. Error in v-on handler: “TypeError: this.$refs.popup.isShow is not a function“
  19. html ios编程工具,DevmyApp:傻瓜式iOS应用程序开发软件
  20. 跳跃性思维的一些特征【转】

热门文章

  1. 技嘉主板WIN7激活记
  2. Codeforces H. Ancient Wisdom
  3. Allegro同组等长走线约束方法
  4. 区块链,下一代互联网?
  5. 越是好的品牌越应该早点做私域
  6. 在window server2012里安装SharePoint2010
  7. LCD1602的引脚定义
  8. 中国移动短信指令大全
  9. 计算机英语forward,勇往直前:forward的用法解析
  10. python使用selenium 打开谷歌浏览器闪退, 怎么解决