Description
间桐慎二是间桐家著名的废柴,有一天,他在学校随机了一组随机数列, 准 备使用他那强大的人工智能求出其最长上升子序列,但是天有不测风云,人有旦
夕祸福,柳洞一成路过时把间桐慎二的水杯打翻了…… 现在给你一个长度为 n 的整数序列,其中有一些数已经模糊不清了,现在请
你任意确定这些整数的值,使得最长上升子序列最长(为何最长呢?因为间桐慎 二向来对自己的人品很有信心) 。
Input
第一行一个正整数 n。 接下来 n 行,第 i 行若为“K x” ,则表示第 i 个数可以辨认且这个数为 x; 若为“N” ,则表示第i
个数已经辨认不清了。
Output
第一行一个整数,表示最长的最长上升子序列长度。
Sample Input
4
K 1
N
K 2
K 3
Sample Output
3
HINT
对于100%的数据,n ≤ 100000,|x| ≤ 10^9
题解
没猜到结论….
发现一定可以构造出一种解,使得每个N都在这个解中出现过
如果有一种最优解没有包含所有N,那么我们将任意没有出现过的N替代他后面第一个被选了的K
把序列中所有N去掉,已知数x记为x-num 其中num表示他之前出现的N的个数
裸跑lis,答案加上n即可
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
struct LSnode{int y,p;}w[100005];int len;
bool LScmp(LSnode n1,LSnode n2){return n1.y<n2.y;}
int s[200005],tt;
int lowbit(int x){return x&-x;}
void change(int x,int c){while(x<=tt)s[x]=max(s[x],c),x+=lowbit(x);}
int findmx(int x){int ret=0;while(x>=1)ret=max(ret,s[x]),x-=lowbit(x);return ret;}
int n,a[200005],f[200005];
char ch[10];
int main()
{
scanf("%d",&n);int num=0;
for(int i=1;i<=n;i++)
{
scanf("%s",ch+1);
if(ch[1]=='N')num++;
else
{
int x;scanf("%d",&x);
len++;w[len].y=x-num;w[len].p=len;
}
}
sort(w+1,w+1+len,LScmp);
a[w[1].p]=1;tt=1;
for(int i=2;i<=len;i++)
{
if(w[i].y!=w[i-1].y)tt++;
a[w[i].p]=tt;
}
int ans=0;
for(int i=1;i<=len;i++)
{
f[i]=findmx(a[i]-1)+1;ans=max(ans,f[i]);
change(a[i],f[i]);
}
printf("%d\n",ans+num);
return 0;
}