题目大意:给定一个数列,数列中的一些位置可以任意指定,求LIS的最大值
首先我们可以发现一个性质:一定存在某组最优解满足所有N都在其中
这个是显然的,如果某组最优解中某个N没有被选择,那么用他挤掉他后面第一个选择了的K,答案不变
然后做法就显然了,我们把K都拎出来,每个数减掉他前面N的个数,然后求出LIS,加上N的数量即为答案
证明,充分性显然,必要性:
将任意一组选择了所有N的最优解拎出来,把N删掉后,每个K减掉前面N的个数都是一个LIS
必要性得证
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 100100
using namespace std;
int n,m,ans,cnt;
int a[M],f[M];
int main()
{
int i;
char p[10];
cin>>n;
for(i=1;i<=n;i++)
{
scanf("%s",p);
if(p[0]=='K')
scanf("%d",&a[++m]),a[m]-=cnt;
else
++cnt;
}
memset(f,0x3f,sizeof f);
for(i=1;i<=m;i++)
{
int pos=lower_bound(f+1,f+n+1,a[i])-f;
ans=max(ans,pos);f[pos]=a[i];
}
cout<<ans+cnt<<endl;
return 0;
}