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. EF--复杂类型

    介绍EF复杂类型的文章 我理解的复杂类型就是简化了编码的操作,实际上在数据库中还是按照约定生成相应的类似"类名_类名"的表结构 public class CompanyAddres ...

  2. 基于Mybatis的Mysql数据库文档生成工具,支持生成docx(原创)

    今天不写android--也写写数据库相关的东西 -------------------- 今日老夫闲来无事,设计了一款数据库文档生成工具 眼下仅仅支持mysql 主要是生成docx的 下载链接:下载 ...

  3. Class 找出一个整形数组中的元素的最大值

    目的:找出一个整形数组中的元素的最大值   以下,我们用类和对象的方法来做.   #include<iostream> using namespace std; class Array_m ...

  4. [Javascript] Understand common misconceptions about ES6's const keyword

    Values assigned with let and const are seen everywhere in JavaScript. It's become common to hear the ...

  5. POJ 题目3020 Antenna Placement(二分图)

    Antenna Placement Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7011   Accepted: 3478 ...

  6. HDOJ1796 How many integers can you find(dfs+容斥)

    How many integers can you find Time Limit: 12000/5000 MS (Java/Others)    Memory Limit: 65536/32768 ...

  7. NUnit Console Command Line

    https://github.com/nunit/docs/wiki/Console-Command-Line The console interface runner is invoked by a ...

  8. Mac OS X10.9安装的Python2.7升级Python3.4步骤详解

    Mac OS X10.9安装的Python2.7升级Python3.4步骤详解 Mac OS X10.9默认带了Python2.7,不过现在Python3.4.0出来了,如果想使用最新版本,赶紧升级下 ...

  9. SNMP简单概述

    一.SNMP简单概述 1.1.什么是Snmp SNMP是英文"Simple Network Management Protocol"的缩写,中文意思是"简单网络管理协议& ...

  10. WCF WEB HTTP请求 WCF REST FUL

    首先上点概念WCF 很好的支持了 REST 的开发, 而 RESTful 的服务通常是架构层面上的考虑. 因为它天生就具有很好的跨平台跨语言的集成能力,几乎所有的语言和网络平台都支持 HTTP 请求, ...