[bzoj4282][乱搞]慎二的随机数列

博客围绕求解含模糊数的整数序列的最长上升子序列展开。给出序列输入输出格式及样例,还给出题解,指出可构造解使每个模糊数都在解中出现,去掉模糊数后对已知数处理,裸跑最长上升子序列算法,答案加上模糊数个数。

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值