关于最长上升子序列问题,非常好地体现了贪心和递归的思想方法。关于该问题的nlogn解法可以结合代码理解:
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+1;
int a[N],f[N],len=1,i,j,n;
void find(int l,int r,int x)
{
if (l==r)
{
f[l]=x;
return;
}
int mid=(l+r)/2;
if (f[mid]<x&&f[mid+1]>x) f[mid+1]=x;//如果这里加上等号
//就会变成不严格上升的子序列
if (x>f[mid+1]) find(mid+1,r,x);
if (x<f[mid])
{
if (mid==1) a[mid]=a[i];//这里需要特判一下,不然就往回找了
else find(l,mid,x);
}
}
int main()
{
cin>>n;
for (i=1;i<=n;++i) cin>>a[i];
f[1]=a[1];
for (i=2;i<=n;++i)
{
if (a[i]>f[len]) f[++len]=a[i];//发现比最后一个数还大就加上
else find(1,len,a[i]);//比最后一个数小就物尽其用
//去找在f上升子序列中第一个比a[i]大的数,将其替换掉
}
return 0;
}