版权声明:本文为博主原创文章,未经博主允许必须转载。 https://blog.csdn.net/C20181220_xiang_m_y/article/details/88900002
题目分析:
DP,设
表示答案序列以第i个点结尾的最长长度,
为第i个点的数。
那么当
时,有
,这个转移需要满足
移一下项就是
,可以看出,这样的转移已经保证了
,那么只需要按a[i]排序,把i-a[i]放进树状数组里面,每次找最大值即可。
Code:
#include<cstdio>
#include<cctype>
#include<algorithm>
#define maxn 100005
char cb[1<<15],*cs,*ct;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
inline void read(int &a){
char c;while(!isdigit(c=getc()));
for(a=c-'0';isdigit(c=getc());a=a*10+c-'0');
}
using namespace std;
int n,ans;
struct node{
int x,id;
bool operator < (const node &p)const{return x==p.x?id>p.id:x<p.x;}
}a[maxn];
int arr[maxn];
void upd(int i,int d){for(;i<=n;i+=i&-i) arr[i]=max(arr[i],d);}
int qmax(int i){int s=0;for(;i;i-=i&-i) s=max(s,arr[i]);return s;}
int main()
{
read(n);
for(int i=1;i<=n;i++) read(a[i].x),a[i].id=i;
sort(a+1,a+1+n);
for(int i=1,x;i<=n;i++) if(a[i].id>=a[i].x) ans=max(ans,x=qmax(a[i].id-a[i].x+1)+1),upd(a[i].id-a[i].x+1,x);
printf("%d",ans);
}