BZOJ 4282 慎二的隨機數列 LIS

題目大意:給定一個數列,數列中的一些位置可以任意指定,求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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章