1. 程式人生 > >BZOJ 1609 Usaco Eating Together

BZOJ 1609 Usaco Eating Together

%d 序列 eth 爆炸 turn tdi nlogn ++ num

看完題目第一眼的感覺就是求一個最長不上升子序列 和 最長不下降子序列
O(N^2)一定是跑不過去的 所以要寫個O(NlogN)的算法
結果成功寫挫~
思維難度不大,註意二分容易寫爆炸。

#include <cstdio>
#include <algorithm>
#include <cstring>
 
using namespace std;
 
int n;
int num[30005],b[30005];
int Max,MAX;
 
void DOWN(){
    Max = 1;
    int j;
    b[Max] = num[Max];
    
for(int i=2;i<=n;i++){ if(num[i]<=b[Max]) j = ++Max; else{ int l = 1; int r = Max+1; while(l<r){ int m = (l+r)>>1; if(b[m]>=num[i]) l = m+1; else r = m; } j
= l; } b[j] = num[i]; } /*for(int i=1;i<=Max;i++){ printf("b[%d]:%d\n",i,b[i]); }*/ MAX=Max; } void UP(){ memset(b,0,sizeof(b)); Max = 1; int j ; b[Max] = num[Max]; for(int i=2;i<=n;i++){ if(num[i]>=b[Max]) j=++Max;
else{ int l = 1; int r = Max+1; while(l<r){ int m = (l+r)>>1; if(b[m]<=num[i]) l = m+1; else r = m; } j= l; } b[j] = num[i]; } /*for(int i=1;i<=Max;i++){ printf("b[%d]:%d\n",i,b[i]); }*/ MAX = max(Max,MAX); } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&num[i]); DOWN(); UP(); printf("%d\n",n-MAX); return 0; }

BZOJ 1609 Usaco Eating Together