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
Data Constraint
对于10%的数据,n ≤ 1000,不存在“N”。
对于30%的数据,“N”的个数≤ 20,0 ≤ x ≤ 100000。
对于100%的数据,n ≤ 100000,|x| ≤ 10^9。
Solution
首先提出一个猜想:一定有一个最优方案包含所有的N
证明如下:
当有N在方案序列外时,可以使方案更优,不成立;
当有N在方案序列内时,可以代替其中一个数,从而使这个方案包含这个N。
那么猜想成立。所以答案就相当于把确定的数拿出来,每个数等于原数减去之前N的个数。
然后对此序列做一次最长上升子序列,再加上N的总个数即可!
Code
#include<cstdio>
#include<algorithm>
using namespace std;
int ans,sum;
int f[100001];
inline int read()
{
int data=0,w=1; char ch=0;
while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
if(ch=='-') ch=getchar(),w=-1;
while(ch>='0' && ch<='9') data=data*10+ch-'0',ch=getchar();
return data*w;
}
int main()
{
int n=read();
f[0]=-1e9;
for(int i=1;i<=n;i++)
{
char ch=getchar();
while(ch!='K' && ch!='N') ch=getchar();
if(ch=='N') sum++; else
{
int x=read()-sum;
if(f[ans]<x) f[++ans]=x; else f[lower_bound(f+1,f+1+ans,x)-f]=x;
}
}
printf("%d",ans+sum);
return 0;
}