zoukankan      html  css  js  c++  java
  • codevs 3289 花匠

    题目:codevs 3289 花匠

    链接:http://codevs.cn/problem/3289/

    这道题有点像最长上升序列,但这里不是上升,是最长“波浪”子序列。用动态规划可以解决,方程类似最长上升子序列:

    f[i]=max(f[j])  ( 1≤j≤i-1 && ( (f[j]%2=1 && A[j]<A[i] ) || (j%2=0 && A[j]>A[i]) )  )

    p[i]=max(p[i])  (  1≤j≤i-1 && ( (p[j]%2=1 && A[j]>A[i] ) || (j%2=0 && A[j]<A[i]) )  )

    结果:

    ans=max(f[n],p[n])

    ...写出来,很恶心的方程,因为题目中是有两种情况,第一种是 第一个元素 < 第二个元素 开始的波浪序列,另一种是 第一个元素 > 第二个元素 开始的波浪序列。我这里的f[i]是第一种情况算出来的最长波浪序列,p[i]是第二种情况算出来的最长波浪序列,然后最后的答案是两者之间选一个最大的。这样用o(n²)的算法可以达成,但是注意,题目中的数据量是10,000 ,肯定时间要超,所以还是要用优化。

    最长上升子序列中可以用线段树优化,那么这里怎么优化呢?

    我的笨笨做法是开4个线段树:maxfj[],maxfo[],maxpj[],maxpo[]。

    maxfj[]维护f[i]是奇数的最大值,maxfo[]维护f[i]是偶数的最大值。

    maxpj[]维护p[i]是奇数的最大值,maxpo[]维护p[i]是偶数的最大值。

    因为f[i]中,当f[i]是奇数的时候,区间是1到A[i]-1中的最大值,而当f[i]是偶数的时候,区间是A[i]+1到n的最大值(因为是严格单调,所以要+1或-1)。

                   当p[i]是奇数的时候,区间是A[i]+1到n的最大值,而当p[i]是偶数的时候,区间是1到A[i]-1中的最大值。

    所以不能同时维护,要分开来,因此就是4个线段树。

    当然,A[i]的值很大,要做离散化。

    大致思路就是这样吧。

    附代码:

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<iostream>
      4 using namespace std;
      5 const int maxn=100010;
      6 
      7 int n,maxfj[maxn*4],maxfo[maxn*4],f[maxn],p[maxn],maxpj[maxn*4],maxpo[maxn*4];
      8 
      9 struct u
     10 {
     11     int v,r;
     12     bool operator <(const u &rhs) const
     13     {
     14         return v<rhs.v;
     15     }
     16 }A[maxn];
     17 
     18 bool cmp(u a,u b)
     19 {
     20     return a.r<b.r;
     21 }
     22 
     23 int w,v;
     24 void updatefj(int o,int L,int R)
     25 {
     26     if(L==R) maxfj[o]=max(maxfj[o],v);
     27     else
     28     {
     29         int M=(L+R)/2;
     30         if(w<=M) updatefj(o*2,L,M); else updatefj(o*2+1,M+1,R);
     31         maxfj[o]=max(maxfj[o*2],maxfj[o*2+1]);
     32     }
     33 }
     34 
     35 int y1,y2,ans;
     36 void queryfj(int o,int L,int R)
     37 {
     38     if(y1<=L && R<=y2) ans=max(ans,maxfj[o]);
     39     else
     40     {
     41         int M=(L+R)/2;
     42         if(y1<=M) queryfj(o*2,L,M);
     43         if(y2>M) queryfj(o*2+1,M+1,R);
     44     }
     45 }
     46 void updatefo(int o,int L,int R)
     47 {
     48     if(L==R) maxfo[o]=max(maxfo[o],v);
     49     else
     50     {
     51         int M=(L+R)/2;
     52         if(w<=M) updatefo(o*2,L,M); else updatefo(o*2+1,M+1,R);
     53         maxfo[o]=max(maxfo[o*2],maxfo[o*2+1]);
     54     }
     55 }
     56 
     57 void queryfo(int o,int L,int R)
     58 {
     59     if(y1<=L && R<=y2) ans=max(ans,maxfo[o]);
     60     else
     61     {
     62         int M=(L+R)/2;
     63         if(y1<=M) queryfo(o*2,L,M);
     64         if(y2>M) queryfo(o*2+1,M+1,R);
     65     }
     66 }
     67 void updatepj(int o,int L,int R)
     68 {
     69     if(L==R) maxpj[o]=max(maxpj[o],v);
     70     else
     71     {
     72         int M=(L+R)/2;
     73         if(w<=M) updatepj(o*2,L,M); else updatepj(o*2+1,M+1,R);
     74         maxpj[o]=max(maxpj[o*2],maxpj[o*2+1]);
     75     }
     76 }
     77 
     78 void querypj(int o,int L,int R)
     79 {
     80     if(y1<=L && R<=y2) ans=max(ans,maxpj[o]);
     81     else
     82     {
     83         int M=(L+R)/2;
     84         if(y1<=M) querypj(o*2,L,M);
     85         if(y2>M) querypj(o*2+1,M+1,R);
     86     }
     87 }
     88 
     89 void updatepo(int o,int L,int R)
     90 {
     91     if(L==R) maxpo[o]=max(maxpo[o],v);
     92     else
     93     {
     94         int M=(L+R)/2;
     95         if(w<=M) updatepo(o*2,L,M); else updatepo(o*2+1,M+1,R);
     96         maxpo[o]=max(maxpo[o*2],maxpo[o*2+1]);
     97     }
     98 }
     99 
    100 void querypo(int o,int L,int R)
    101 {
    102     if(y1<=L && R<=y2) ans=max(ans,maxpo[o]);
    103     else
    104     {
    105         int M=(L+R)/2;
    106         if(y1<=M) querypo(o*2,L,M);
    107         if(y2>M) querypo(o*2+1,M+1,R);
    108     }
    109 }
    110 
    111 int main()
    112 {
    113     cin>>n;
    114     for(int i=1;i<=n;i++) cin>>A[i].v,A[i].r=i;
    115     //离散化 
    116     sort(A+1,A+n+1);
    117     for(int i=1,nw=1;i<=n;i++)
    118     {
    119         f[i]=1,p[i]=1;//顺便做的f[],p[]初始化 
    120         if(A[i+1].v!=A[i].v) nw++,A[i].v=nw-1;
    121         else A[i].v=nw;
    122     } 
    123     sort(A+1,A+n+1,cmp);
    124      
    125     w=A[1].v,v=f[1];
    126     updatefj(1,1,n);
    127     updatepj(1,1,n);
    128 
    129     for(int i=2;i<=n;i++)
    130     {
    131         y1=1,y2=A[i].v-1,ans=0;
    132         if(y2>=y1) queryfj(1,1,n);//注意,因为有A[i]-1,所以要判断区间的存在 
    133         y1=A[i].v+1,y2=n;
    134         if(y2>=y1) queryfo(1,1,n);
    135         f[i]=ans+1;
    136         v=f[i],w=A[i].v;
    137         if(f[i]%2==1) updatefj(1,1,n);
    138         else updatefo(1,1,n);
    139         
    140         y1=1,y2=A[i].v-1,ans=0;
    141         if(y2>=y1) querypo(1,1,n);
    142         y1=A[i].v+1,y2=n;
    143         if(y2>=y1) querypj(1,1,n);
    144         p[i]=ans+1;
    145         v=p[i],w=A[i].v;
    146         if(p[i]%2==1) updatepj(1,1,n);
    147         else updatepo(1,1,n);
    148     }
    149     
    150     cout<<max(f[n],p[n]);
    151     return 0;
    152 }
  • 相关阅读:
    学习ASP.NET MVC3(5) Controller
    关于测试
    [JAVA SE] Java反射机制
    Windows 8 的软件开发架构
    Servlet生命周期与工作原理
    展望未来,总结过去10年的程序员生涯,给程序员小弟弟小妹妹们的一些总结性忠告(转载)
    JAVA小游戏代码(剪刀石头布)
    [JAVA SE] JSP中pageEncoding和charset区别,中文乱码解决方案
    我是工程师,不是编译器
    自己对三层架构理论的理解
  • 原文地址:https://www.cnblogs.com/frankscode/p/6259957.html
Copyright © 2011-2022 走看看