给出长度为N的数组,找出这个数组的最长递增子序列。(递增子序列是指,子序列的元素是递增的)
例如:5 1 6 8 2 4 5 10,最长递增子序列是1 2 4 5 10。
输入
第1行:1个数N,N为序列的长度(2 <= N <= 50000) 第2 - N + 1行:每行1个数,对应序列的元素(-10^9 <= S[i] <= 10^9)
输出
输出最长递增子序列的长度。
输入示例
8 5 1 6 8 2 4 5 10
输出示例
5
AC代码:
#include<iostream>
using namespace std;
const int maxn=1e5;
int f[maxn],a[maxn];
int find(int l,int r,int x)
{
while(l<r)
{
int mid=(l+r)/2;
if(f[mid]<x)
l=mid+1;
else
r=mid;
}
return l;//比x小的最大的那个数的下标
}
int LIS(int n)
{
int len=0;
for(int i=0;i<n;i++)
{
int k=find(0,len,a[i]);
f[k]=a[i];
if(k==len)
len++;
}
return len;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
int ans=LIS(n);
cout<<ans<<endl;
return 0;
}
更简单的代码:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1e5;
const int INF=0x3f3f3f3f;
int a[maxn],dp[maxn];
int main()
{
int n;
memset(dp,INF,sizeof(dp));
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
for(int i=0;i<n;i++)
{
*lower_bound(dp,dp+n,a[i])=a[i];
}
cout<<lower_bound(dp,dp+n,INF)-dp<<endl;
return 0;
}