动态规划

最长上升子序列问题(LIS)。给定n个整数,按从左到右的顺序选出尽量多的整数,组成一个上升子序列(子序列可以理解为:删除0个或多个数,其他数的顺序不变)。例如序列1, 6, 2, 3, 7, 5,可以选出上升子序列1, 2, 3, 5,也可以选出1, 6, 7,但前者更长。选出的上升子序列中相邻元素不能相等。

最容易想到的办法就是用一个数组f[i]保存到达第i个数的LIS

初始化f[i]=1

更新 f[i]=max{f[j]+1,f[i]|a[j]<a[i],1<=j<i}

即在第i位置前的比i小的最大的LIS+1

时间复杂度O(n^2)

#include<cstdio>
#include<iostream>//vj1098
#define ll long long
#define _max(a,b) ((a)>(b)?(a):(b))
using namespace std;
const int N=;
int n,a[N],ans;
int f[N],g[N];
int main()
{
freopen("sample.in","r",stdin);
cin>>n;
for(int i=;i<=n;i++)
scanf("%d",&a[i]),f[i]=g[i]=;
for(int i=;i<=n;i++)
for(int j=;j<i;j++)
if(a[j]<a[i])
f[i]=_max(f[i],f[j]+);
for(int i=n;i>=;i--)
for(int j=n;j>i;j--)
if(a[j]<a[i])
g[i]=_max(g[i],g[j]+);
for(int i=;i<=n;i++)
ans=_max(ans,f[i]+g[i]-);
cout<<n-ans;
return ;
}

从蓝书和网上学到了一种更高效的O(nlogn)的算法

大概思路如下

  d[i]表示以i结尾的最长的LIS的长度,则d[i]=max{0,d[j]|j<i,Aj<Ai}+1,最终答案是max{d[i]}。如果LIS中的元素可以相等,把小于号改成小于等于号即可。

  假如已经计算出两个状态a,b满足Aa<Ab,且d[a]=d[b],则对于后续所有状态i(即i>a且i>b)来说,a并不会比b差——如果b满足Ab<Aa的条件,a也满足。换句话说,如果我们只保留a,一定不会丢失最优解。

  这样,对于相同的d值,最需要保留A最小的一个。我们用g[i]表示d值为i的最小状态编号(如果不存在,g[i]定义为正无穷)。根据上推理可证明

  g[1]<=g[2]<=g[3]<=……<=g[n]

#include<cstdio>
#include<iostream>
#define ll long long
#define _max(a,b) ((a)>(b)?(a):(b))
using namespace std;
const int N=;
int n,k,a[N],b[N],o[N],ans,ma,mb;
int j,da[N],db[N],len,la,lb,mid;
int findpos(int *d,int l,int r,int key){
while(l<=r){
mid=(l+r)>>;
if(key>d[mid]){
if(key<=d[mid+])
return mid;
else l=mid+;
}else r=mid-;
}return ;
}
int main(){
cin>>n>>k;
for(int i=;i<=n;i++) scanf("%d",o+i);
for(int i=;i<k;i++) o[i]<o[k]?a[++la]=o[i]:la=la;
for(int i=k+;i<=n;i++) o[i]>o[k]?b[++lb]=o[i]:lb=lb;
da[]=a[],len=,j=;
for(int i=;i<=la;i++)da[a[i]>da[len]?++len:findpos(da,,len,a[i])+]=a[i];
db[]=b[],len=,j=;
for(int i=;i<=lb;i++)db[b[i]>db[len]?++len:findpos(db,,len,b[i])+]=b[i];
for(int i=la;i>=;i--)da[i]?ans+=i,i=:i=i;
for(int i=lb;i>=;i--)db[i]?ans+=i,i=:i=i;
cout<<ans+;
return ;
}

汝佳的code核心

for(int i=;i<=n;i++)g[i]=INF;
for(int i=;i<=n;i++){
int k=lower_bound(g+,g+n+,A[i])-g;
d[i]=k;
g[k]=a[i];
}

LIS最长上升子序列O(n^2)与O(nlogn)的算法的更多相关文章

  1. 算法设计 - LCS 最长公共子序列&&最长公共子串 &&LIS 最长递增子序列

    出处 http://segmentfault.com/blog/exploring/ 本章讲解:1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度:2. 与之类似但不同的 ...

  2. POJ - 3903 Stock Exchange(LIS最长上升子序列问题)

    E - LIS Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u   Descripti ...

  3. hdu 5256 序列变换(LIS最长上升子序列)

    Problem Description 我们有一个数列A1,A2...An,你现在要求修改数量最少的元素,使得这个数列严格递增.其中无论是修改前还是修改后,每个元素都必须是整数. 请输出最少需要修改多 ...

  4. POJ 3903 Stock Exchange (E - LIS 最长上升子序列)

    POJ 3903    Stock Exchange  (E - LIS 最长上升子序列) 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action ...

  5. 动态规划模板1|LIS最长上升子序列

    LIS最长上升子序列 dp[i]保存的是当前到下标为止的最长上升子序列的长度. 模板代码: int dp[MAX_N], a[MAX_N], n; int ans = 0; // 保存最大值 for ...

  6. POJ 1887 Testingthe CATCHER (LIS:最长下降子序列)

    POJ 1887Testingthe CATCHER (LIS:最长下降子序列) http://poj.org/problem?id=3903 题意: 给你一个长度为n (n<=200000) ...

  7. LIS 最长递增子序列

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

  8. 动态规划——E (LIS())最长上升子序列

    E - LIS Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Stat ...

  9. LIS 最长递增子序列问题

    一,    最长递增子序列问题的描述 设L=<a1,a2,…,an>是n个不同的实数的序列,L的递增子序列是这样一个子序列Lin=<aK1,ak2,…,akm>,其中k1< ...

随机推荐

  1. CU上看到的一个简单的算法帖子

    今天也是明白了,编程与数学的关系.例子很简单,不过能说明问题. 如果我们优化算法只从计算机特性来考虑,那么我们的人脑也成了计算机.不要忘记数学对于算法的重要影响. 题目: 返回小于数字 N 的所有 3 ...

  2. 跟我一起玩Win32开发(转自CSDN-东邪独孤)

    跟我一起玩Win32开发(1):关于C++的几个要点 跟我一起玩Win32开发(2):完整的开发流程 跟我一起玩Win32开发(3):窗口的重绘 跟我一起玩Win32开发(4):创建菜单 跟我一起玩W ...

  3. ASP.NET MVC中使用DropDownList

    在ASP.NET MVC中,尽管我们可以直接在页面中编写HTML控件,并绑定控件的属性,但更方便的办法还是使用HtmlHelper中的辅助方法.在View中,包含一个类型为HtmlHelper的属性H ...

  4. ASP.NET MVC4中@model使用多个类型实例的方法

    转http://blog.csdn.net/hulihui/article/details/48199897

  5. 接入百度语音SDK的步骤

    1.导入依赖库 SystemConfiguration.framework AudioToolbox.framework UIkit.framework AVFoundation.framework ...

  6. 第九章 springboot + mybatis + 多数据源 (AOP实现)(转载)

    本编博客转发自:http://www.cnblogs.com/java-zhao/p/5415896.html 1.ShopDao package com.xxx.firstboot.dao; imp ...

  7. Oracle 12c 的新功能:模式匹配查询

    模式匹配SQL 在一系列的数据行中辨识出某种模式是一种广泛需求的功能,但在以前的SQL中是不可能的.有许多解决方法,但这些都很难写,很难理解,而且执行效率低下.在Oracle数据库中,从12c开始,你 ...

  8. 对 web.config 节点信息进行加密

    记录一下,免得以后再网上找 项目中,数据库访问链接字符串配置在web.config中,明文的,应客户需求需改成密文,so,需要加密. 一开始想的是需要重写configuration什么什么的,最后发现 ...

  9. aix 维护常用命令

    errpt   - dH  :如果有记录表示硬故障件出现.#向ibm报修 mail:关键错误信息会以mail方式发给root用户.#根据报错程序联系相应厂家. df  -g: 文件系统不可以,当/va ...

  10. Sql Server 常用操作

    --DDL触发器CREATE   TRIGGER [TR_create_drop_alter_Table] ON DATABASE FOR CREATE_TABLE,DROP_table,ALTER_ ...