考虑转移f[i]=max{f[j]}+1当(1<=ai-aj<=i-j)
于是我们把a数组按ai为第一关键字,i-ai为第二关键字升序排序,这样只要满足i-ai>=j-aj更新。就可以然后维护d[],d[k]表示长度为k时i-ai最小为多少,对于每个i二分查找最优决策,然后再把自己的值假如决策集合即可。
代码:
#include <cstdio>
#include <algorithm>
using namespace std;
using namespace std;
const int N=1e5+10;
pair<int,int> a[N];
int d[N];
int cnt,n,len;
int main() {
scanf("%d",&n);
for(int i=1,x; i<=n; i++) {
scanf("%d",&x);
if (x-i>0) continue;
a[++cnt].second=x;
a[cnt].first=i-a[cnt].second;
}
sort(a+1,a+1+cnt);
for(int i=1; i<=cnt; i++) {
int j=lower_bound(d,d+len,a[i].second)-d;
d[j]=a[i].second;
len=max(len,j+1);
}
printf("%d",len);
return 0;
}