zoukankan      html  css  js  c++  java
  • 方伯伯的玉米田(树状数组优化)(三维偏序)

    zzh学长留的毒瘤题......

    首先这题先明白一个性质:

         当我们选择增区间的高度时,我们应该将所选的增加的左端点到n全增大,因为我们要求

    最后成的单调不下降序列长度最大,所以这样增稳赚不亏。。。。

    然后那么我们发现这题最后的点的最优高度是a[n]+K确定的

    设数组含义f[j][k]表示当前玉米高度j,k次操作的最长序列长度

    并且我们可以把此题看作三位偏序:

    1. 当前玉米位置i,由1-i-1转移

    2. 当前玉米高度j,由1-j转移

    3.当前玉米已操作k,由1-k-1转移

    用树状数组维护j,k,(很显然了.....)

    (为了节省内存所以我们第一位循环是i,这样保证我们的i是有序的,就不需要写在数组里,

    其实i,j,k,任选两位都行,只是为了省内存嘛.......)

    注意点:

    1.循环k时倒序,(显然嘛.....当前的k若是正序,他的插入会影响当前位k的枚举)

    2.预处理要注意,根据你的枚举来定,当然也可以不

    3.ans值不一定选中最后一个点

     1 #include<map>
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<string>
     8 #include<vector>
     9 #define int long long
    10 using namespace std;
    11 int c[511][5501];
    12 int a[11001];
    13 int maxn;
    14 int lowbit(int x){return x&(-x);}
    15 int n,K;
    16 void add(int x,int y,int sum)//x 第几个操作 y 高度 k第k操作
    17 {
    18     for(int i=x;i<=K+1;i+=lowbit(i))
    19     {
    20         for(int j=y;j<=maxn+K;j+=lowbit(j))
    21         {
    22               c[i][j]=max(c[i][j],sum);
    23         }
    24     }
    25 }
    26 int query(int x,int y)
    27 {
    28      int ans=0;
    29      for(int i=x;i>=1;i-=lowbit(i))
    30      {
    31           for(int j=y;j>=1;j-=lowbit(j))
    32           {
    33               ans=max(ans,c[i][j]);
    34           }
    35      }
    36      return ans;
    37 }
    38 int ans=0;
    39 signed main()
    40 {
    41     scanf("%lld%lld",&n,&K);
    42     for(int i=1;i<=n;++i)
    43     {
    44          scanf("%lld",&a[i]);
    45          maxn=max(a[i],maxn);    
    46     }
    47     for(int i=1;i<=n;++i)
    48     {
    49         for(int j=K;j>=0;--j)
    50         {
    51              int th=query(j+1,a[i]+j)+1;
    52              //printf("dp[%lld][%lld]=%lld
    ",j,a[i]+j);
    53              ans=max(th,ans);
    54              add(j+1,a[i]+j,th);   
    55         }
    56     }
    57     //int ans=query(K+1,a[n]+K);
    58     printf("%lld
    ",ans);
    59 }
    View Code

     

  • 相关阅读:
    有没有可能两个不相等的对象有有相同的 hashcode?
    适配器模式和装饰器模式有什么区别?
    JRE、JDK、JVM 及 JIT 之间有什么不同?
    我们能在 Switch 中使用 String 吗?
    解释对象/关系映射集成模块?
    解释 Java 堆空间及 GC?
    List、Set、Map 和 Queue 之间的区别?
    Java 中,Comparator 与 Comparable 有什么不同?
    两个相同的对象会有不同的的 hash code 吗?
    Java 中的编译期常量是什么?使用它又什么风险?
  • 原文地址:https://www.cnblogs.com/Wwb123/p/11272933.html
Copyright © 2011-2022 走看看