这里是Joe学习的笔记,如果能帮助到你,那我受宠若惊!

首先把题目链接发一下:P1439 【模板】最长公共子序列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

这里参考@皎月半洒花 大佬的详细讲解!

最长上升子序列:LIS

n^2做法:

for(int i=1;i<=n;i++){dp[i]=1;//初始化 for(int j=1;j<i;j++)//枚举i之前的每一个j if(data[j]<data[i] && dp[i]<dp[j]+1)//用if判断是否可以拼凑成上升子序列,//并且判断当前状态是否优于之前枚举//过的所有状态,如果是,则↓ dp[i]=dp[j]+1;//更新最优状态 }

nlogn做法:

int n;cin>>n;for(int i=1;i<=n;i++){cin>>a[i];f[i]=0x7fffffff;//这里的f[i]表示上升序列为i的上升子序列的最小末尾数值
//如果长度为i的子序列结尾元素越小,后面的元素更放标加入这条假设可能为结果的上升子序列中。//初始值要设为INF/*原因很简单,每遇到一个新的元素时,就跟已经记录的f数组当前所记录的最长上升子序列的末尾元素相比较:如果小于此元素,那么就不断向前找,直到找到一个刚好比它大的元素,替换;反之如果大于,么填到末尾元素的下一个q,INF就是为了方便向后替换啊!*/ }f[1]=a[1];int len=1;//通过记录f数组的有效位数,求得个数 /*因为上文中所提到我们有可能要不断向前寻找,所以可以采用二分查找的策略,这便是将时间复杂度降成nlogn级别的关键因素。*/ for(int i=2;i<=n;i++){int l=0,r=len,mid;if(a[i]>f[len])f[++len]=a[i];//如果刚好大于末尾,暂时向后顺次填充 else {while(l<r){   mid=(l+r)/2;if(f[mid]>a[i])r=mid;//如果仍然小于之前所记录的最小末尾,那么不断//向前寻找(因为是最长上升子序列,所以f数组必//然满足单调) else l=mid+1; }f[l]=min(a[i],f[l]);//更新最小末尾 }}cout<<len;

两个序列中的最长公共子序列LCS

n^2:

#include<iostream>
using namespace std;
int dp[1001][1001],a1[2001],a2[2001],n,m;
int main()
{   //这里的dp[i][j]表示第一个串的前i位,第二个串的前j位的LCS的长度//dp[i][j]表示两个串从头开始,直到第一个串的第i位 //和第二个串的第j位最多有多少个公共子元素 cin>>n>>m;for(int i=1;i<=n;i++)scanf("%d",&a1[i]);for(int i=1;i<=m;i++)scanf("%d",&a2[i]);for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){dp[i][j]=max(dp[i-1][j],dp[i][j-1]);if(a1[i]==a2[j])dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);//因为更新,所以++; }cout<<dp[n][m];
}

因为两个序列都是1~n的全排列,那么两个序列元素互异且相同,也就是说只是位置不同罢了,那么我们通过一个map数组将A序列的数字在B序列中的位置表示出来——

因为最长公共子序列是按位向后比对的,所以a序列每个元素在b序列中的位置如果递增,就说明b中的这个数在a中的这个数整体位置偏后,可以考虑纳入LCS——那么就可以转变成nlogn求用来记录新的位置的map数组中的LIS。

#include<iostream>
#include<cstdio>
using namespace std;
int a[100001],b[100001],map[100001],f[100001];
int main()
{int n;cin>>n;for(int i=1;i<=n;i++){scanf("%d",&a[i]);map[a[i]]=i;}for(int i=1;i<=n;i++){scanf("%d",&b[i]);f[i]=0x7fffffff;}int len=0;f[0]=0;for(int i=1;i<=n;i++){int l=0,r=len,mid;if(map[b[i]]>f[len])f[++len]=map[b[i]];else {while(l<r){ mid=(l+r)/2;if(f[mid]>map[b[i]])r=mid;else l=mid+1; }f[l]=min(map[b[i]],f[l]);}}cout<<len;return 0
}

然后是@heey大佬的解释

首先看到这道题很容易一下就想到dp(n^2),但是看看数据范围,放弃dp,再看一看它题目给出的,这两串数都是1到n的全排列,说白了就上下两个串中的元素都是相同的,只有顺序不同而已,那么知道这个,我们又怎么来解决这道题呢?

我们可以以第一个串为标准,用第二个串来匹配第一个串,看能匹配多少,所以,其实第一个串的每个数字其实影响不大,只有知道它对应了第二串的哪个数字就好了,那么我们为什么不把他给的串重新定义一下?

比如他的样例:3 2 1 4 5 我们把他变成 1 2 3 4 5 用一个数组记录一下每个数字变成了什么,相当于离散化了一下3-1;2-2;1-3;4-4;5-5;

现在我们的第二串1 2 3 4 5 按我们离散化的表示:3 2 1 4 5

可能有些人已经懂了,我们把第一个串离散化后的数组是满足上升,反过来,满足上升的也就是满足原串的排列顺序的,(如果你不懂的话可以多看几遍这个例子)O(∩_∩)O~

好了 ,现在的问题就变成了求一个最长不下降序列!好了!解决完成!

线性动态规划以及最长匹配长度相关推荐

  1. KMP算法下,长为n的字符串中匹配长度为m的子串的复杂度为O(m+n)

    kmp算法完成的任务是:给定两个字符串O和f,长度分别为n和 m,判断f是否在O中出现,如果出现则返回出现的位置.常规方法是遍历O的每一个位置,然后从该位置开始和f进行匹配,但是这种方法的复杂度是 O ...

  2. 【动态规划】线性动态规划

    吐槽:动态规划这个东西,只要推不出状态转移方程,一切都白搭 基础知识 一. 动态规划 动态规划中最重要的三个概念:最优子结构,重复子问题,无后效性. 最优子结构:如果问题的最优解所包含的子问题的解也是 ...

  3. 动态规划法求最大字段和时间复杂度_九章算法 | 动态规划:最长上升子序列

    给定一个整数序列,找到最长上升子序列(LIS),返回LIS的长度. 在线评测地址:LintCode 领扣 说明 最长上升子序列的定义: 最长上升子序列问题是在一个无序的给定序列中找到一个尽可能长的由低 ...

  4. 动态规划之----最长公共子序列

    动态规划算法的基本要素: 1)最优子结构 当问题的最优解包含了其子问题的最优解时,称该问题具有最优子结构性质.问题的最优子结构性质提供了该问题可用动态规划算法求解的最重要线索. 在动态规划算法中,利用 ...

  5. 获取字符串中的.前面的长度_算法连载之求解不含有重复字符的最长子串长度...

    问题 给定一个字符串,找出其中不含有重复字符的最长子串长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc" ...

  6. 第十七章:线性动态规划

    通过上一章对01背包问题的学习,我相信同学们都动态规划都有了一个新的认识.在我们利用动态规划解决问题的过程通常会有以下几个常见的专业术语,分别是:状态定义,状态的转移,初始化和边界条件.下面我们对这几 ...

  7. 第32题 最长匹配括号

    题目: 找出字符串中最长匹配括号的长度,如")()())()()(",结果为4 思路: )  (  ) (  )  ) (  ) (  )  ( 0 1 2 3 4 5 6 7 8 ...

  8. 【动态规划】最长公共上升子序列

    问题 F: [动态规划]最长公共上升子序列 时间限制: 5 Sec  内存限制: 64 MB 提交: 34  解决: 9 [提交] [状态] [命题人:admin] 题目描述 研究发现,大猩猩的基因序 ...

  9. 化工热力学补考成功,几天没有头脑了,赶紧赏自己几题Leetcode动态规划算法最长系列

    @Author:Runsen @Date:2020/10/9 "恭喜你昨天,化工热力学补考成功!" "区区化工热力学还想让我重修,只不过浪费了我九月一半的精力和十月的九成 ...

最新文章

  1. 【评论】一个老程序员的建议
  2. N5-用两个栈来实现一个队列
  3. oracle oem 监控,DBA手记:OEM罪几何?-空间监控的性能问题
  4. 正则表达式那些事儿(一)
  5. bbs小项目整理(五)(登录模块的完成)
  6. Luogu1886 滑动窗口 /【模板】单调队列
  7. 在苹果系统MacOS上安装PowerDesigner16.5
  8. linux下安装交叉编译器
  9. EasyRecovery15永久免费数据恢复软件
  10. 4.4 matlab三维曲线(plot3函数、fplot3函数)
  11. z-blogPHP在西部数码虚拟主机上遇到WTS-WAF错误拦截情况,协商好久他们还是妥协了...
  12. idea发现git出现cannot run git:cannot identify version of git executable :no response
  13. 红帽为什么要加入阿里云的朋友圈?
  14. 低成本快速上链 智臻链开放联盟网络正式对外开放
  15. 002:Python爬虫Urllib库全面分析
  16. python-pygame实现飞机大战-3-发射子弹以及击中敌机
  17. 使用PHP的curl爬取百度搜索页相关搜索词
  18. 修改完bug GIT的提交流程 及NVM的常用指令
  19. 关于sockjs.js?9be2:1606 GET http://****/sockjs-node/info?t=1581148413474 net::ERR_CONNECTI 错误解决方案
  20. Git中文件夹灰色无法打开问题解决

热门文章

  1. 解决启动nginx报错问题:[warn] 4450#0: the “user“ directive makes sense only if the master process runs......
  2. 中国条形码申请 条形码申请好处 中国条码续期
  3. php网站无法预缆,解决wp-super-cache无法(预)缓存问题
  4. 人生苦短我用python谁说的_人生苦短,我用 Python
  5. 今天学习VI编辑器的使用方法
  6. 服装店小程序开发方案,服装店利用多端抖音微信百度小程序商城,轻松摆脱销售难的问题
  7. Hive 超赞的解析 Json 数组的函数
  8. 超频稳定测试软件,超频第三步:稳定性测试Kombuster
  9. python学习之深浅拷贝
  10. android webview 选择图片上传,适配Android WebView支持上传图片,视频