最长上升子序列LIS(Longest Increasing Subsequence)
Posted 远山笑你。
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最长上升子序列LIS(Longest Increasing Subsequence)相关的知识,希望对你有一定的参考价值。
算法1:
时间复杂度:O(n^2):
我们依次遍历整个序列,每一次求出从第一个数到当前这个数的最长上升子序列,直至遍历到最后一个数字为止,然后再取dp数组里最大的那个即为整个序列的最长上升子序列。我们用dp[i]来存放序列1-i的最长上升子序列的长度,那么dp[i]=max(dp[j])+1,(j∈[1, i-1]); 显然dp[1]=1,我们从i=2开始遍历后面的元素即可。
#include<iostream> #include<algorithm> #include<string.h> #include<stdio.h> using namespace std; int main() { int n,a[100]; int dp[100]; memset(dp,0,sizeof(dp)); scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d",&a[i]); } dp[0]=1; for(int i=1;i<n;i++) { for(int j=0;j<n;j++) { if((a[i]>a[j])&&((dp[j]+1)>dp[i])) { dp[i]=dp[j]+1; } } } sort(dp,dp+n); printf("%d\n",dp[n-1]); return 0; }
算法2:
时间复杂度:(NlogN):
除了算法一的定义之外,增加一个数组b,b[i]用以表示长度为i最长子序列的最后一个数最小可以是多少。易证:i<j时,b[i]<b[j]。
在二分查找时,一直更新b[]内容,设此时b的总长度为k,
若1. arr[i] >= b[k], 则b[k+1] = arr[i];
若2. arr[i] < b[k], 则在b[1..k]中用二分搜索大于arr[i]的最小值,返回其位置pos,然后更新b[pos]=arr[i]。
以上是关于最长上升子序列LIS(Longest Increasing Subsequence)的主要内容,如果未能解决你的问题,请参考以下文章
最长递增子序列 (LIS) Longest Increasing Subsequence
CF1304D Shortest and Longest LIS
[kuangbin带你飞]专题十二 基础DP1 N - Longest Ordered Subsequence POJ - 2533(最长上升子序列LIS)