[NOIP2013]花匠
Posted QYP_2002
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[NOIP2013]花匠相关的知识,希望对你有一定的参考价值。
Description
花匠栋栋种了一排花,每株花都有自己的高度。花儿越长越大,也越来越挤。栋栋决定把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空间长大,同时,栋栋希望剩下的花排列得比较别致。 具体而言,栋栋的花的高度可以看成一列整数h1, h2, … , hn。设当一部分花被移走后,剩下的花的高度依次为g1, g2, … , gm,则栋栋希望下面两个条件中至少有一个满足: 条件 A:对于所有的1 ≤ i < m / 2,g_2i > g_2i?1,且g_2i > g_2i+1; 条件 B:对于所有的1 ≤ i < m / 2,g_2i < g_2i?1,且g_2i < g_2i+1。 此处2i及2i-1,2i+1都为下标。 注意上面两个条件在m = 1时同时满足,当m > 1时最多有一个能满足。 请问,栋栋最多能将多少株花留在原地。
Input
输入的第一行包含一个整数 n,表示开始时花的株数。 第二行包含 n 个整数,依次为h1, h2,… , hn,表示每株花的高度。
Output
输出一行,包含一个整数 m,表示最多能留在原地的花的株数。
Sample Input
5 5 3 2 1 2
Sample Output
3
Hint
对于 20%的数据,n ≤ 10; 对于 30%的数据,n ≤ 25; 对于 70%的数据,n ≤ 1000,0 ≤ hi ≤ 1000; 对于 100%的数据,1 ≤ n ≤ 100,000,0 ≤ hi ≤ 1,000,000,所有的h_i随机生成,所有随机数服从某区间内的均匀分布。
思路:{按a,b两种情况暴力dp,O(n^2),然后用权值线段树优化即可,最终复杂度O(nlogn)。}
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<algorithm> 6 #define RG register 7 #define lowbit ((k)&(-k)) 8 #define rs ((o<<1)|1) 9 #define ls (o<<1) 10 #define mid ((l+r)>>1) 11 #define maxx 1000003 12 #include<queue> 13 using namespace std; 14 int a[maxx],dp[maxx],sum[maxx],n,tree1[maxx*4],tree2[maxx*4]; 15 void Insert1(int o,int l,int r,int p,int num){ 16 if(l==r){tree1[o]=num;return;} 17 if(mid<p)Insert1(rs,mid+1,r,p,num); 18 else Insert1(ls,l,mid,p,num); 19 tree1[o]=max(tree1[rs],tree1[ls]); 20 } 21 void Insert2(int o,int l,int r,int p,int num){ 22 if(l==r){tree2[o]=num;return;} 23 if(mid<p)Insert2(rs,mid+1,r,p,num); 24 else Insert2(ls,l,mid,p,num); 25 tree2[o]=max(tree2[rs],tree2[ls]); 26 } 27 int ask1(int o,int l,int r,int L,int R){ 28 if(l>=L&&r<=R)return tree1[o]; 29 if(mid<L)return ask1(rs,mid+1,r,L,R); 30 else if(mid>=R)return ask1(ls,l,mid,L,R); 31 else return max(ask1(rs,mid+1,r,L,R),ask1(ls,l,mid,L,R)); 32 } 33 int ask2(int o,int l,int r,int L,int R){ 34 if(l>=L&&r<=R)return tree2[o]; 35 if(mid<L)return ask2(rs,mid+1,r,L,R); 36 else if(mid>=R)return ask2(ls,l,mid,L,R); 37 else return max(ask2(rs,mid+1,r,L,R),ask2(ls,l,mid,L,R)); 38 } 39 int main(){ 40 scanf("%d",&n); 41 for(RG int i=1;i<=n;++i)scanf("%d",&a[i]),a[i]++; 42 dp[1]=sum[1]=1;Insert1(1,0,maxx,a[1],1); 43 for(RG int i=2;i<=n;++i){int Max1=ask1(1,0,maxx,0,a[i]-1),Max2=ask2(1,0,maxx,a[i]+1,maxx); 44 if(Max1>Max2){ 45 dp[i]=Max1+1; 46 Insert2(1,0,maxx,a[i],dp[i]); 47 } 48 else dp[i]=Max2+1,Insert1(1,0,maxx,a[i],dp[i]); 49 } 50 int ans=dp[n];memset(tree1,0,sizeof(tree1));memset(tree2,0,sizeof(tree2)); 51 memset(dp,0,sizeof(dp)); 52 dp[1]=sum[1]=1;Insert1(1,0,maxx,a[1],1); 53 for(RG int i=2;i<=n;++i){int Max1=ask1(1,0,maxx,a[i]+1,maxx),Max2=ask2(1,0,maxx,0,a[i]-1); 54 if(Max1>Max2){ 55 dp[i]=Max1+1; 56 Insert2(1,0,maxx,a[i],dp[i]); 57 } 58 else dp[i]=Max2+1,Insert1(1,0,maxx,a[i],dp[i]); 59 } 60 ans=max(ans,dp[n]);cout<<ans; 61 return 0; 62 }
以上是关于[NOIP2013]花匠的主要内容,如果未能解决你的问题,请参考以下文章