题解:
0可以转化成任意整数,包括负数,显然求LIS时尽量把0都放进去必定是正确的。因此我们可以把0拿出来,对剩下的做O(nlogn)的LIS,统计结果的时候再算上0的数量。为了保证严格递增,我们可以将每个权值S[i]减去i前面0的个数,再做LIS,就能保证结果是严格递增的。
ACcode:
#include <bits/stdc++.h>
#define maxn 100010
using namespace std;
int dp[maxn],b[maxn];
int cnt=1;
void DP(int n,int zero){
dp[1]=b[1];
int tmp=1;
for(int i=2;i<=n;++i)
if(b[i]>dp[tmp])
dp[++tmp]=b[i];
else {
int pos=lower_bound(dp+1,dp+tmp,b[i])-dp;
dp[pos]=b[i];
}
printf("Case #%d: %d\n",cnt++,tmp+zero);
}
int main(){
int loop,n;
scanf("%d",&loop);
while(loop--){
scanf("%d",&n);
int zero=0,pos=0;
for(int i=1;i<=n;++i){
int tmp;
scanf("%d",&tmp);
if(tmp!=0)b[++pos]=tmp-zero;
else zero++;
}
if(!pos){
printf("Case #%d: %d\n",cnt++,n);
continue;
}
DP(pos,zero);
}
return 0;
}