zoukankan      html  css  js  c++  java
  • [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   freopen("1.in","r",stdin);
    41   freopen("1.out","w",stdout);
    42   scanf("%d",&n);
    43   for(RG int i=1;i<=n;++i)scanf("%d",&a[i]),a[i]++;
    44   dp[1]=sum[1]=1;Insert1(1,0,maxx,a[1],1);
    45   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);
    46     if(Max1>Max2){
    47       dp[i]=Max1+1;
    48       Insert2(1,0,maxx,a[i],dp[i]);
    49     }
    50     else dp[i]=Max2+1,Insert1(1,0,maxx,a[i],dp[i]);
    51   }
    52   int ans=dp[n];memset(tree1,0,sizeof(tree1));memset(tree2,0,sizeof(tree2));
    53   memset(dp,0,sizeof(dp));
    54   dp[1]=sum[1]=1;Insert1(1,0,maxx,a[1],1);
    55   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);
    56     if(Max1>Max2){
    57       dp[i]=Max1+1;
    58       Insert2(1,0,maxx,a[i],dp[i]);
    59     }
    60     else dp[i]=Max2+1,Insert1(1,0,maxx,a[i],dp[i]);
    61   }
    62   ans=max(ans,dp[n]);cout<<ans;
    63   return 0;
    64 }

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #define RG register
    #define lowbit ((k)&(-k))
    #define rs ((o<<1)|1)
    #define ls (o<<1)
    #define mid ((l+r)>>1)
    #define maxx 1000003
    #include<queue>
    using namespace std;
    int a[maxx],dp[maxx],sum[maxx],n,tree1[maxx*4],tree2[maxx*4];
    void Insert1(int o,int l,int r,int p,int num){
      if(l==r){tree1[o]=num;return;}
      if(mid<p)Insert1(rs,mid+1,r,p,num);
      else Insert1(ls,l,mid,p,num);
      tree1[o]=max(tree1[rs],tree1[ls]);
    }
    void Insert2(int o,int l,int r,int p,int num){
      if(l==r){tree2[o]=num;return;}
      if(mid<p)Insert2(rs,mid+1,r,p,num);
      else Insert2(ls,l,mid,p,num);
      tree2[o]=max(tree2[rs],tree2[ls]);
    }
    int ask1(int o,int l,int r,int L,int R){
      if(l>=L&&r<=R)return tree1[o];
      if(mid<L)return ask1(rs,mid+1,r,L,R);
      else if(mid>=R)return ask1(ls,l,mid,L,R);
      else return max(ask1(rs,mid+1,r,L,R),ask1(ls,l,mid,L,R));
    }
    int ask2(int o,int l,int r,int L,int R){
      if(l>=L&&r<=R)return tree2[o];
      if(mid<L)return ask2(rs,mid+1,r,L,R);
      else if(mid>=R)return ask2(ls,l,mid,L,R);
      else return max(ask2(rs,mid+1,r,L,R),ask2(ls,l,mid,L,R));
    }
    int main(){
      freopen("1.in","r",stdin);
      freopen("1.out","w",stdout);
      scanf("%d",&n);
      for(RG int i=1;i<=n;++i)scanf("%d",&a[i]),a[i]++;
      dp[1]=sum[1]=1;Insert1(1,0,maxx,a[1],1);
      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);
        if(Max1>Max2){
          dp[i]=Max1+1;
          Insert2(1,0,maxx,a[i],dp[i]);
        }
        else dp[i]=Max2+1,Insert1(1,0,maxx,a[i],dp[i]);
      }
      int ans=dp[n];memset(tree1,0,sizeof(tree1));memset(tree2,0,sizeof(tree2));
      memset(dp,0,sizeof(dp));
      dp[1]=sum[1]=1;Insert1(1,0,maxx,a[1],1);
      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);
        if(Max1>Max2){
          dp[i]=Max1+1;
          Insert2(1,0,maxx,a[i],dp[i]);
        }
        else dp[i]=Max2+1,Insert1(1,0,maxx,a[i],dp[i]);
      }
      ans=max(ans,dp[n]);cout<<ans;
      return 0;
    }

  • 相关阅读:
    MongoDB_聚合
    MongoDB_基本操作
    MongoDB_"Error parsing YAML config file: yaml-cpp: error at line 3, column 9: illegal map value"解决方法
    MongoDB_安装
    beautifulsoup模块
    python发送邮件
    selenium常用操作
    selenium元素定位
    requests模块的高级用法
    继承
  • 原文地址:https://www.cnblogs.com/zzmmm/p/6922016.html
Copyright © 2011-2022 走看看