1.LIS :

给定一个序列,求它的最长上升子序列(n<=2000)

第一种 O(n^2):

dp[i] 为以i为开头的最长上升子序列长度

code1:

#include<cstdio>
#include<iostream>
using namespace std; int n,ans;
int a[2005],dp[2005]; int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
dp[i]=1;
}
for(int i=1;i<=n;i++) {
for(int j=1;j<i;j++)
if(a[j]<a[i]) dp[i]=max(dp[j]+1,dp[i]);
if(ans<dp[i]) ans=dp[i];
}
printf("%d",ans);
return 0;
}

第二种 O(nlogn):

最长上升子序列存在O(N log N)时间复杂度的算法,概述如下:

考虑两个数a[x]和a[y],若x < y且g[x]==g[y],那么在转移的过程中,选择a[x]更有潜力(证明是显而易见的,可以自己设计几组数据加深理解),可以获得最优的值,所以当g数组的值一样时,应选择最小的数。

按照g[i]==k分类,记录g[i]==k的所有i的最小值,g有两个特点:

1)f[i]在计算过程中单调不升

2)f数组是有序的,g[i]<=g[i+1]

根据这些性质,可以方便地求解:

1)设当前求出的LIS长度为ans(初始值为1),当前元素为a[x]

2)如果a[x]>g[ans],直接加入f数组的末尾,且ans++;否则在f数组中二分查找,找到第一个比a[x]小的数字g[k](使用二分查找实现),g[k+1]=a[x],这样做保证a[x] < =g[k+1](根据性质1,2)

3)最后的ans即为答案

代码中dp[i] 表示长度为i的上升子序列末尾元素最小是多少

code2:

#include<cstdio>

int n,ans;
int a[2005],dp[2005]; int find(int l,int r,int x){//二分查找 用循环也行这里递归
int mid=(l+r)/2;
if(l==mid) return l<x?r:l;//如果前一个满足选前一个不然选第二个
if(dp[mid]<x) return find(mid,r,x);
else return find(l,mid,x);
} int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
dp[++top]=a[1];
for(int i=2;i<=n;i++) {//若a[i]==dp[ans] 跳过
if(a[i]>dp[ans]) dp[++ans]=a[i];//如果恰好可以接上
else if(a[i]<dp[ans]) dp[find(1,ans,a[i])]=a[i];//找到第一个不小于的换掉(手动跑下就明白了)
}
printf("%d",ans);
return 0;
}

2.LCS

给定两个长度分别为n,m的序列S,T求他们的最长公共子序列

设 dp[x][y] 表示S[1..x]与T[1..y]的最长公共子序列的长度

分三种情况:

1.S[x]不在公共子序列中:该情况下dp[x][y]=dp[x-1][y];

2.T[x]不在公共子序列中:该情况下dp[x][y]=dp[x][y-1];

3.当S[x]=T[y]时,S[x]和T[y] 均在公共子序列中:该情况下dp[x][y]=dp[x-1][y-1]+1;

最终dp[x][y] 取以上情况的最大值。

边界 若x=0或y=0 dp[x][y] =0。

复杂度:O(n^2)

code:

#include<cstdio>

int n,m;
int s[2][5000],dp[5000][5000]; int max(int x,int y,int z){
x=x>y?x:y;
x=x>z?x:z;
return x;
} int main(){
scanf("%d",&n);
for(int i=0;i<=1;i++)
for(int j=1;j<=n;j++)
scanf("%d",&s[i][j]); for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) {
if(s[0][i]==s[1][j]) dp[i][j]=dp[i-1][j-1]+1;
dp[i][j]=max(dp[i][j],dp[i-1][j],dp[i][j-1]);
} printf("%d",dp[n][n]);
return 0;
}

最长上升子序列(LIS)与最长公共子序列(LCS)的更多相关文章

  1. 【部分转载】:【lower_bound、upperbound讲解、二分查找、最长上升子序列(LIS)、最长下降子序列模版】

    二分 lower_bound lower_bound()在一个区间内进行二分查找,返回第一个大于等于目标值的位置(地址) upper_bound upper_bound()与lower_bound() ...

  2. 【线型DP模板】最上上升子序列(LIS),最长公共子序列(LCS),最长公共上升子序列(LCIS)

    BEGIN LIS: 一个数的序列bi,当b1 < b2 < … < bS的时候,我们称这个序列是上升的.对于给定的一个序列(a1, a2, …, aN),我们可以得到一些上升的子序 ...

  3. 准备NOIP2017 最长公共子序列(模版)

    一些概念: (1)子序列: 一个序列A = a1,a2,--an,中任意删除若干项,剩余的序列叫做A的一个子序列.也可以认为是从序列A按原顺序保留任意若干项得到的序列.例如:   对序列 1,3,5, ...

  4. LCS问题(最长公共子序列)-动态规划实现

    问题描述: 问题] 求两字符序列的最长公共字符子序列 注意: 并不要求子串(字符串一)的字符必须连续出现在字符串二中. 思路分析: 最优子结构和重叠子问题的性质都具有,所以要采取动态规划的算法 最长公 ...

  5. 动态规划———最长公共子序列(LCS)

    最长公共子序列+sdutoj2080改编: http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Contest/contestproblem/cid/ ...

  6. 算法实践--最长公共子序列(Longest Common Subsquence)

    什么是最长公共子序列 X=ACCG Y=CCAGCA 长度为1的公共子序列: {A} {C} {G} 长度为2的公共子序列:{AC} {CC} {CG} {AG} 长度为3的公共子序列:{ACG} 长 ...

  7. - > 动规讲解基础讲解五——最长公共子序列问题

    一些概念: (1)子序列: 一个序列A = a1,a2,……an,中任意删除若干项,剩余的序列叫做A的一个子序列.也可以认为是从序列A按原顺序保留任意若干项得到的序列. 例如:   对序列 1,3,5 ...

  8. C++动态规划实现查找最长公共子序列

    问题描述: 给定两个序列X={x1,x2,…,xm}和Y={y1,y2,…,yn},找出X和Y的最长公共子序列.(给定两个序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共 ...

  9. 最长公共子序列(LCS)和最长递增子序列(LIS)的求解

    一.最长公共子序列 经典的动态规划问题,大概的陈述如下: 给定两个序列a1,a2,a3,a4,a5,a6......和b1,b2,b3,b4,b5,b6.......,要求这样的序列使得c同时是这两个 ...

随机推荐

  1. 可回味的js代码段

    1,关于bind()----- var name="global"; var person={ name:"person", hello:function(st ...

  2. Poj 1321 棋盘问题 【回溯、类N皇后】

    id=1321" target="_blank">棋盘问题 Time Limit: 1000MS   Memory Limit: 10000K Total Subm ...

  3. java.lang.NoClassDefFoundError: org/json/JSONException

    问题: 解决办法:

  4. Linux用户和组的管理

    一.概述: 1.Linux下的三类用户: (1).超级用户(root)具有操作系统的一切权限UID值均为0 (2).普通用户具有操作系统有限的权限UID值500~6000 (3).伪用户是为了方便系统 ...

  5. 自定义控件三部曲之动画篇(四)——ValueAnimator基本使用

    前言:不要让别人的无知断送了你的梦想,永远坚信你所坚信的. 相关文章: <Android自定义控件三部曲文章索引>:http://blog.csdn.net/harvic880925/ar ...

  6. 车牌识别(end-to-end-for-chinese-plate-recognition)项目搭建基于Mxnet(Python 3.5)

    最近看到geihub上有个车牌识别的项目,感觉很有意思,从上面fork了一下弄到本地自己跑了下.在安装过程中遇到了一些问题,记录如下. 项目github连接:https://github.com/sz ...

  7. AIX&nbsp;常用命令汇总(一)

    命令 内核 如何知道自己在运行 32 位内核还是 64 位内核? 要显示内核启用的是 32 位还是 64 位,可输入以下命令: bootinfo -K 如何知道自己在运行单处理器还是多处理器内核? / ...

  8. jQuery不熟点总结

     jQuery 事件 1 .trigger() 方法触发被选元素的指定事件类型. 2 .delegate() 事件委派  1.不占内存2.可以给未来元素(后期动态添加的元素)添加事件. 2.  添加元 ...

  9. html页面中苹果手机遇到数字换行、样式变形

    在做项目中遇到过几回苹果手机读取html页面时,如果出现一串数字,html页面会折行.变形,最后发现是因为苹果手机的打电话功能,如果html上有数字的话,苹果手机会以为是电话号码,就会改变其样式只需要 ...

  10. WebForm--j简单控件、简单的登录(怎么链接数据库)

    一.简单控件 1.label:边框(边框的颜色.样式.粗细)  是专门显示文字的,   被编译后是    <span id="Label1">Label</spa ...