动态规划

最长上升子序列问题(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. C# basic

    1. output Console.WriteLine("hello world"); 2. naming convention variable: start with lowe ...

  2. WIN32API 自定义颜色下拉列表控件

    效果如下: 原创-转载请著名来源 1,新建颜色属性类“CNColor”: class CNColor { public: COLORREF m_crColor; //颜色RGB值 WCHAR m_cC ...

  3. transitionend的运用案例

    transitionend事件代表着过渡动画结束后 原生的绑定方法 obj.addEventListener('transitionEnd', function(){ //do soming }) 我 ...

  4. SQL 分页

    sql = "SELECT TOP 10000 * " + " FROM(SELECT ROW_NUMBER() OVER(ORDER BY DataArticleID) ...

  5. JS-小球碰撞反弹

    类似于屏保的一种动画,当小球碰到边框时,发生反弹,并且变化颜色. <!DOCTYPE html><html lang="en"><head>   ...

  6. pil

    http://effbot.org/imagingbook/ 一.安装 pip install PIL --allow-external PIL --allow-unverified PIL   出现 ...

  7. 我利用网上特效开发的Jquery插件

    我利用网上特效开发的Jquery插件 代码如下 (function($){ $.fn.Dialogx = function(options) { var defaults={ Width:" ...

  8. C++中关于文件的读写

    在C++的学习过程中,我们时常要用到对文件的操作,下面我们讲一下文件的读写. 首先,读.也就是把已有的文件读到控制台上,那么如何操作呢?首先要将文件操作的输入输出流包含进去. <fstream& ...

  9. springMVC 相对于 Structs 的优势

    智者说,没有经过自己的思考和估量,就不能接受别人的东西.资料只能是一个参考,至于是否正确,还得自己去分辨 SpringMVC相对于Structs的几个优势: 1.springMVC安全性更高,stru ...

  10. cassandra指定数据库路径

    参考 https://docs.datastax.com/en/cassandra/2.1/cassandra/configuration/configCassandra_yaml_r.html 我们 ...