最长上升子序列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
",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]。

原文地址:https://www.cnblogs.com/laoyangtou/p/7191478.html