bzoj1609 / P2896 [USACO08FEB]一起吃饭Eating Together(最长不降子序列)

P2896 [USACO08FEB]一起吃饭Eating Together

显然的最长不升/降子序列,求出最长值,则答案为$n-$最长值(改掉剩下的)。

复杂度$O(nlogn)$

(然鹅有神仙写了$O(n)$模拟)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
#define re register
using namespace std;
void read(int &x){
    char c=getchar();x=0;
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
}
int min(int &a,int &b){return a<b?a:b;}
#define N 30002
int n,a[N],f1[N],f2[N],tp1,tp2;
int main(){
    read(n);
    for(re int i=1;i<=n;++i) read(a[i]);
    f1[tp1=1]=f2[tp2=1]=a[1];
    for(re int i=2;i<=n;++i){//同时维护2个序列
        if(f1[tp1]<=a[i]) f1[++tp1]=a[i];
        else{
            int l=1,r=tp1;
            while(l<r){
                int mid=l+((r-l)>>1);
                if(f1[mid]>a[i]) r=mid;
                else l=mid+1;
            }f1[l]=a[i];
        }
        if(f2[tp2]>=a[i]) f2[++tp2]=a[i];
        else{
            int l=1,r=tp2;
            while(l<r){
                int mid=l+((r-l)>>1);
                if(f2[mid]<a[i]) r=mid;
                else l=mid+1;
            }f2[l]=a[i];
        }
    }printf("%d",min(n-tp1,n-tp2));
    return 0;
}

 

posted @ 2018-10-26 16:20  kafuuchino  阅读(90)  评论(0编辑  收藏  举报