跳到主要内容

最长上升子序列(LIS)

最长上升子序列:找到给定序列的一个子序列,使得这个子序列元素的数值依次递增,并且这个子序列的长度尽可能大。

参考资料

二分查找

for(int i=1;i<=n;i++)
{
int k=lower_bound(b+1,b+n+1,a[i])-b;
b[k]=a[i];
ans=max(ans,k);
}

树状数组

for(int i=1;i<=n;i++)
{
int k=query(a[i]-1)+1;
update(a[i],k);
ans=max(ans,k);
}

例题

洛谷 B3637 最长上升子序列

给定一个长度为 nn 的正整数序列 aia_i,求最长上升子序列的长度。(n5000,ai106n\le5000,a_i\le10^6

#include <bits/stdc++.h>
using namespace std;

using ll=long long;
const int inf=0x3f3f3f3f;
const int N=5005;
int a[N],b[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)b[i]=inf;
int ans=0;
for(int i=1;i<=n;i++)
{
int k=lower_bound(b+1,b+n+1,a[i])-b;
b[k]=a[i];
ans=max(ans,k);
}
cout<<ans<<'\n';
return 0;
}