首页 > 代码库 > NOIp2013 T5 花匠

NOIp2013 T5 花匠

[NOIP2013T5]花匠

Time Limit: 1000ms    Memory Limit: 131072KB
描述Descript.

花匠栋栋种了一排花,每株花都有自己的高度。花儿越长越大,也越来越挤。栋栋决定把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空间长大,同时,栋栋希望剩下的花排列得比较别致。

具体而言,栋栋的花的高度可以看成一列整数?1, ?2, … , ?n。设当一部分花被移走后,剩下的花的高度依次为g1, g2, … , gm,则栋栋希望下面两个条件中至少有一个满足:

条件 A:对于所有的1 ≤ i ≤ m/2,g2i > g2i−1,且g2i > g2i+1

条件 B:对于所有的1 ≤ i ≤ m/2,g2i < g2i−1,且g2i < g2i+1

注意上面两个条件在m = 1时同时满足,当m > 1时最多有一个能满足。

请问,栋栋最多能将多少株花留在原地。

输入Input
输入的第一行包含一个整数 ,表示开始时花的株数。 
第二行包含 个整数,依次为?1, ?2,… , ?n,表示每株花的高度。
输出Output
输出一行,包含一个整数m,表示最多能留在原地的花的株数。
样例Sample

输入数据


5 5 3 2 1 2 

输出数据


3
备注Hint

【输入输出样例说明】

有多种方法可以正好保留 3 株花,例如,留下第 1、4、5 株,高度分别为 5、1、2,满足条件 B。

 

【数据范围】

对于 20%的数据,n ≤ 10;

对于 30%的数据,n ≤ 25;

对于 70%的数据,n ≤ 1000,0 ≤ ?i ≤ 1000;

对于 100%的数据,1 ≤ n ≤ 100,000,0 ≤ ?i ≤ 1,000,000,所有的?i随机生成,所有随机数服从某区间内的均匀分布。

 

裸dp+线段树

 1 #include<queue> 2 #include<vector> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<iostream> 7 #include<algorithm> 8 using namespace std; 9 const int N = 200010;10 #define Ch1 T[kth].lc[i]11 #define Ch2 T[kth].rc[i]12 #define For(i,n) for(int i=1;i<=n;i++)13 #define Rep(i,l,r) for(int i=l;i<=r;i++)14 15 struct tnode{16     int l[N],r[N],mid[N];17     int max[N],rt,lc[N],rc[N];18 }T[2];19 20 struct flower{21     int h,id,rh;22 }p[N];23 24 bool fcmp(flower A,flower B){return A.rh<B.rh;}25 bool scmp(flower A,flower B){return A.id<B.id;}26 int Lim,n,cnt,f[N][2];27 28 void init(){29     scanf("%d",&n);30     For(i,n) {31         scanf("%d",&p[i].rh);32         p[i].id=i;33     }34     sort(p+1,p+n+1,fcmp);35     p[1].h=1;36     Rep(i,2,n)37       if(p[i].rh==p[i-1].rh) p[i].h=p[i-1].h;38       else                   p[i].h=p[i-1].h+1;39     Lim=p[n].h;40     sort(p+1,p+n+1,scmp);41 }42 43 void Build(int kth,int &i,int l,int r){44     i=++cnt;45     T[kth].l[i]=l;T[kth].r[i]=r;T[kth].mid[i]=(l+r)>>1;46     if(l==r) return;47     Build(kth,Ch1,l,T[kth].mid[i]);Build(kth,Ch2,T[kth].mid[i]+1,r);48 }49 50 void Modify(int kth,int i,int x,int delta){51     if(T[kth].l[i]==T[kth].r[i]){52         T[kth].max[i]=max(T[kth].max[i],delta);53         return;54     }55     if(x<=T[kth].mid[i]) Modify(kth,Ch1,x,delta);56     else                 Modify(kth,Ch2,x,delta);57     T[kth].max[i]=max(T[kth].max[Ch1],T[kth].max[Ch2]);58 }59 60 int query(int kth,int i,int l,int r){61     if(l>r) return 0;62     if(l==T[kth].l[i]&&r==T[kth].r[i]) return T[kth].max[i];63     if(r<=T[kth].mid[i]) return query(kth,Ch1,l,r);else64     if(l>T[kth].mid[i])  return query(kth,Ch2,l,r);else65     return max(query(kth,Ch1,l,T[kth].mid[i]),query(kth,Ch2,T[kth].mid[i]+1,r));66 }67 68 void DP(){69     f[1][0]=1;70     f[1][1]=1;71     Modify(0,T[0].rt,p[1].h,1);72     Modify(1,T[1].rt,p[1].h,1);73     Rep(i,2,n){74         f[i][0]=query(1,T[1].rt,p[i].h+1,Lim)+1;75         Modify(0,T[0].rt,p[i].h,f[i][0]);76         f[i][1]=query(0,T[0].rt,1,p[i].h-1)+1;77         Modify(1,T[1].rt,p[i].h,f[i][1]);78     }79     printf("%d\n",max(f[n][0],f[n][1]));80 }81 82 int main(){83     init();84     Build(0,T[0].rt,1,Lim);cnt=0;85     Build(1,T[1].rt,1,Lim);86     DP();87     return 0;88 }

 

NOIp2013 T5 花匠