码迷,mamicode.com
首页 > 其他好文 > 详细

LIS 堆优化

时间:2019-07-06 20:55:30      阅读:114      评论:0      收藏:0      [点我收藏+]

标签:最长上升子序列   name   人性   http   --   lis   数组   数列   clu   

LIS 问题描述

给出一个数列,找出其中最长的单调递减(或递增)子序列。
例如,A{10,22,9,33,21,50,41,60,80} LIS 的长度是 6,LIS 为 {10,22,33,50,60,80}。

分析

定义 f[i] 表示以 A[i] 结尾的 LIS 的长度,动态转移方程如下:
f[i]=max(f[i],f[j]+1) (j<i and A[j]<A[i])

更人性化的解读参考 GavinZheng- 最长上升子序列

时间复杂度 O(n^2)

方案优化

用 l[i] 表示已遍历的长度为 i 的 LIS最小的结尾数字
则可证明,l[] 数组的元素保持单调上升,于是用二分优化,

#include<iostream>
#include<cstdio>
using namespace std;
int n,a,l[10001],cnt;
int low_bound(int * arr,int l,int r,int v){while(l<r){int mid=(l+r+1)>>1;
        if(arr[mid]>=v)r=mid-1;
        else l=mid;
    }
    return l;
}
int main(){cin>>n;
    for(int i=1;i<=n;i++){cin>>a;
        int j=low_bound(l,0,cnt,a);
        if(++j>cnt)l[++cnt]=a;
        if(l[j]>a)l[j]=a;
    }
    cout<<cnt;
    return 0;
}

时间复杂度 O(nlogn)

LIS 堆优化

标签:最长上升子序列   name   人性   http   --   lis   数组   数列   clu   

原文地址:https://www.cnblogs.com/sshwy/p/11144066.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!