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; }