关于LIS和LCS问题的o(nlogn)解法
o(n^2)解法就不赘述了,直接解释o(nlogn)解法
LIS最长递增子序列;
先明确一个结论:在长度最大为len的递增序列里若末尾元素越小,该递增序列越容易和后面的子序列构造出一个更长的递增子序列。也即认为,长度为len的递增子序列中末尾元素最小的那种最需要保留。我们不妨称这个目前找到序列为到目前为止的 最优序列。
因此设置一个数组lis[i]其中 i 表示此时最大递增序列的长度,数组值表示此时达到 i 的最优序列(也即 长度为len的递增子序列中末尾元素最小的那种)的末尾元素。
那么此时只需遍历一遍输入数据,维护lis的上述特性,则最后所得的lis数组的长度就是要求的len。
不多言,结合代码理解:
- #include<iostream>
- #include<cstdio>
- using namespace std;
- const int maxn=1e5+;
- int a[maxn];
- int n;
- int lis[maxn];
- int len=;
- int find(int x){
- int l=,r=len,m;
- while(l<r){
- m=l+(r-l)/;
- if(lis[m]>=a[x]){//这里若去掉等号即为 非严格递增序列
- r=m;
- }
- else{
- l=m+;
- }
- }
- return l;
- }
- int main(void){
- scanf("%d",&n);
- for(int i=;i<=n;i++)scanf("%d",&a[i]);
- lis[]=a[];
- for(int i=;i<=n;i++){
- if(a[i]>lis[len]){
- lis[++len]=a[i];
- }
- else{
- int pos=find(i);
- lis[pos]=a[i];
- }
- }
- printf("%d",len);
- return ;
- }
LCS最长公共子序列:
最长公共子序列 的 nlogn 的算法本质是 将该问题转化成 最长增序列(LIS),因为 LIS 可以用nlogn实现,所以求LCS的时间复杂度降低为 nlogn。
假设有两个序列 s1[ 1~6 ] = { a, b, c , a, d, c }, s2[ 1~7 ] = { c, a, b, e, d, a, b }。
记录s1中每个元素在s2中出现的位置, 再将位置按降序排列, 则上面的例子可表示为:
loc( a)= { 6, 2 }, loc( b ) = { 7, 3 }, loc( c ) = { 1 }, loc( d ) = { 5 }。
将s1中每个元素的位置按s1中元素的顺序排列成一个序列s3 = { 6, 2, 7, 3, 1, 6, 2, 5, 1 }。
在对s3求LIS得到的值即为求LCS的答案。(这点我也只是大致理解,读者可以自己理解甚至证明。)
这里给出全排列情况下的代码(即两个序列长度相同,数字组成相同,无重复元素)
- #include<iostream>
- #include<cstdio>
- #include<cstdlib>
- using namespace std;
- const int maxn=1e6+;
- int n,len=;
- int lis[maxn];
- int a[maxn];
- int b[maxn];
- int loc[maxn];
- int find(int x){
- int l=,r=len,m;
- while(l<r){
- m=l+(r-l)/;
- //if(lis[m]>=b[x]){//智障错误,找了那么久。。
- if(lis[m]>=x){
- r=m;
- }
- else l=m+;
- }
- return l;
- }
- int main(void){
- scanf("%d",&n);
- for(int i=;i<=n;i++)scanf("%d",&a[i]);
- for(int i=;i<=n;i++){
- scanf("%d",&b[i]);
- loc[b[i]]=i;
- }
- for(int i=;i<=n;i++){
- b[i]=loc[a[i]];
- }
- // for(int i=1;i<=n;i++)printf("%d",b[i]) ;//
- // printf("\n");
- if(n!=)lis[++len]=b[];
- for(int i=;i<=n;i++){
- if(b[i]>lis[len]){
- lis[++len]=b[i];
- }
- else{
- int pos=find(b[i]);
- lis[pos]=b[i];
- }
- }
- printf("%d",len);
- return ;
- }
关于LIS和LCS问题的o(nlogn)解法的更多相关文章
- LIS LCS n^2和nlogn解法 以及LCIS
首先介绍一下LIS和LCS的DP解法O(N^2) LCS:两个有序序列a和b,求他们公共子序列的最大长度 我们定义一个数组DP[i][j],表示的是a的前i项和b的前j项的最大公共子序列的长度,那么由 ...
- LIS和LCS LCIS
首先介绍一下LIS和LCS的DP解法O(N^2) LCS:两个有序序列a和b,求他们公共子序列的最大长度 我们定义一个数组DP[i][j],表示的是a的前i项和b的前j项的最大公共子序列的长度,那么由 ...
- O(nlogn)LIS及LCS算法
morestep学长出题,考验我们,第二题裸题但是数据范围令人无奈,考试失利之后,刻意去学习了下优化的算法 一.O(nlogn)的LIS(最长上升子序列) 设当前已经求出的最长上升子序列长度为len. ...
- LIS与LCS的nlogn解法
LIS(nlogn) #include<iostream> #include<cstdio> using namespace std; ; int a[maxn]; int n ...
- UVa 111 History Grading (简单DP,LIS或LCS)
题意:题意就是坑,看不大懂么,结果就做不对,如果看懂了就so easy了,给定n个事件,注意的是, 它给的是第i个事件发生在第多少位,并不是像我们想的,第i位是哪个事件,举个例子吧,4 2 3 1, ...
- DP---DAG、背包、LIS、LCS
DP是真的难啊,感觉始终不入门路,还是太弱了┭┮﹏┭┮ DAG上的DP 一般而言,题目中如果存在明显的严格偏序关系,并且求依靠此关系的最大/最小值,那么考虑是求DAG上的最短路或者是最长路.(据说 ...
- 【LIC】O(nlogn)解法
[LIC--最长递增子序列问题] 在一列数中寻找一些数,这些数满足:任意两个数a[i]和a[j],若i<j,必有a[i]<a[j],这样最长的子序列称为最长递增子序列. O(nlogn)算 ...
- 拦截导弹nlogn解法
题目 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国 ...
- DP练习 最长上升子序列nlogn解法
openjudge 百练 2757:最长上升子序列 总时间限制: 2000ms 内存限制: 65536kB 描述 一个数的序列bi,当b1 < b2 < ... < bS的时候, ...
随机推荐
- Deploying Cloud Foundry on OpenStack Juno and XenServer (Part II)
link http://rabbitstack.github.io/deploying-cloud-foundry-on-openstack-juno-and-xenserver-part-ii/ L ...
- 数据一致性和io类型
版权声明:本文由高剑林原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/106 来源:腾云阁 https://www.qclo ...
- Excel 2010 如何在Excel的单元格中加入下拉选项
http://jingyan.baidu.com/article/03b2f78c4ba8a05ea237ae95.html 第一步:打开excel文档,选中需加入下拉选项的单元格. 第二步:点击 ...
- Java初学者笔记二:关于类的常见知识点汇总
一.Java的类: Java的类是Java的基本概念了,基本的定义语法我就不提了,自己也不会忘了的,下面分成几个模块介绍: 1.Java的类定义时候的修饰符 2.Java的类的继承与派生 二.Java ...
- iOS5 ARC学习笔记:strong、weak等详解
2013-03-25 13:41 佚名 oschina 字号:T | T iOS5中加入了新知识,就是ARC,其实我并不是很喜欢它,因为习惯了自己管理内存.但是学习还是很有必要的.现在我们看看iOS5 ...
- 微信小程序 --- 绘画
cavans及context详解 绘画API的使用 游戏的制作
- oracle之用户名密码包含特殊字符时候怎么使用sqlplus登录
oracle有时候用户密码包含一些特殊字符直接登录会报错,需要使用以下方式登录sqlplus sqlplus 'username/"password"' PS:整体使用单引号括起来 ...
- What are Traceroute, Ping, Telnet and Nslookup commands?
https://help.maximumasp.com/KB/a445/connectivity-testing-with-ping-telnet-tracert-and-pathping-.aspx ...
- Vanish/squid
http://www.yl1001.com/article/5291411898652918.htm HTTP加速 简单的说,在本次测试中,Varnish将来自80的请求转发到后端的nginx8080 ...
- talib 中文文档(五):文档导航
Documentation 安装和问题 快速使用 高级应用 方法分类 Overlap Studies 重叠的研究 Momentum Indicators 动量指标 Volume Indicators ...