zoukankan      html  css  js  c++  java
  • BZOJ2924 : [Poi1998]Flat broken lines

    首先旋转坐标系

    $x'=x-y$

    $y'=-x-y$

    则对于一个点,它下一步可以往它左上角任意一个点连线。

    根据Dilworth定理,答案=这个偏序集最长反链的长度。

    设f[i]为到i点为止的最长反链长度,则

    f[i]=max(f[j])+1,j在i的左下角

    按x坐标排序后用树状数组优化DP即可,时间复杂度$O(nlog n)$。

    #include<cstdio>
    #include<algorithm>
    #define N 30010
    int n,i,j,x,y,b[N],bit[N],f[N],ans;
    struct P{int x,y;}a[N];
    inline bool cmp(P a,P b){return a.x<b.x;}
    inline void up(int&a,int b){if(a<b)a=b;}
    inline void ins(int x,int y){for(;x<=n;x+=x&-x)up(bit[x],y);}
    inline int ask(int x){int t=0;for(;x;x-=x&-x)up(t,bit[x]);return t;}
    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 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(x),read(y),a[i].x=x-y,a[i].y=b[i]=-x-y;
      for(std::sort(a+1,a+n+1,cmp),std::sort(b+1,b+n+1),i=1;i<=n;i=j){
        for(j=i;j<=n&&a[j].x==a[i].x;j++)up(ans,f[j]=ask((a[j].y=lower(a[j].y))-1)+1);
        for(j=i;j<=n&&a[j].x==a[i].x;j++)ins(a[j].y,f[j]);
      }
      return printf("%d",ans),0;
    }
    

      

  • 相关阅读:
    程序测试与调试
    运行及总结
    《人,绩效和职业道德》及博客读后感
    图书馆管理系统程序设计
    设计类图
    图书馆管理系统程序测试计划
    图书馆管理系统UML建模
    团队分工
    竞争性需求分析
    实践作业三 结对项目
  • 原文地址:https://www.cnblogs.com/clrs97/p/4712249.html
Copyright © 2011-2022 走看看