先把0都去掉,然后不是0的数,减去它前面有多少个0(因为是严格单调增的
nlogn求LIS
用d[] 记录,当前为止,d[i]表示到目前为止,长度为i的上升子序列最末最小为d[i]。。。d[]肯定是不严格单调增的。。
lower_bound。。。前开后闭区间,返回>=val的第一个位置
int pos =lower_bound(d+1, d+len+1, a[i])- d;
#include <iostream>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
#define FOR(i,j,k) for(int i=j;i<=k;i++)
int a[100010];
int d[100010];
int main() {
int T;
scanf("%d",&T);
FOR(z,1,T){
int n;
scanf("%d" ,&n);
FOR(i,1,n)
scanf("%d" ,&a[i]);
int sum =0;
int i =1;
for(;i<=n;i++)
{
if(a[i] ==0)
sum++;
else break;
}
if(i == n+1){
printf("Case #%d: %d\n",z ,sum);
continue;
}
d[1] = a[i]-sum;
int len =1;
i++;
for(;i<= n;i++)
{
if(a[i] == 0) sum++;
else{
a[i]-=sum;
if(a[i] > d[len])
{
len++;
d[len] =a[i];
}
else{
int pos =lower_bound(d+1, d+len+1, a[i])- d;
d[pos] =a[i];
}
}
}
//FOR(i,1,len) cout<<d[i]<<" ";
// cout<<len<<" "<<sum<<endl;
printf("Case #%d: %d\n",z ,len+sum);
}
return 0;
}