zoukankan      html  css  js  c++  java
  • BZOJ1109 : [POI2007]堆积木Klo

    f[i]表示第i个在自己位置上的最大值

    则f[i]=max(f[j])+1

    其中

    j<i

    a[j]<a[i]

    a[i]-a[j]<=i-j -> j-a[j]<=i-a[i]

    i-a[i]>=0

    j-a[j]>=0

    发现后两项可以推出第一项,所以是一个LIS问题,排序后树状数组优化DP即可,时间复杂度$O(nlog n)$。

    #include<cstdio>
    #include<algorithm>
    #define N 100010
    int n,i,j,k,a[N],b[N],bit[N],t,f[N],ans;
    struct E{int x,y;E(){}E(int _x,int _y){x=_x,y=_y;}}e[N];
    inline bool cmp(E a,E b){return a.x<b.x;}
    inline int lower(int x){
      int l=1,r=n,mid,t;
      while(l<=r)if(b[mid=(l+r)>>1]<=x)l=(t=mid)+1;else r=mid-1;
      return t;
    }
    inline void ins(int x,int y){for(;x<=n;x+=x&-x)if(bit[x]<y)bit[x]=y;}
    inline void ask(int x){for(;x;x-=x&-x)if(t<bit[x])t=bit[x];}
    inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
    int main(){
      for(read(n),i=1;i<=n;i++)read(j),e[i]=E(j,i-j),b[i]=i-j;
      std::sort(e+1,e+n+1,cmp),std::sort(b+1,b+n+1);
      for(i=1;i<=n;i=j){
        for(j=i;j<=n&&e[j].x==e[i].x;j++)if(e[j].y>=0){
          t=0,ask(e[j].y=lower(e[j].y));
          if(ans<(f[j]=++t))ans=t;
        }
        for(j=i;j<=n&&e[j].x==e[i].x;j++)if(e[j].y>=0)ins(e[j].y,f[j]);
      }
      return printf("%d",ans),0;
    }
    

      

  • 相关阅读:
    如何向线程传递参数
    IntelliJ IDEA 13 Keygen
    单链表的基本操作
    顺序表静态查找
    有向图的十字链表表存储表示
    BF-KMP 算法
    图的邻接表存储表示(C)
    二叉树的基本操作(C)
    VC远控(三)磁盘显示
    Android 数独游戏 记录
  • 原文地址:https://www.cnblogs.com/clrs97/p/4614898.html
Copyright © 2011-2022 走看看