• RMQ (Range Minimum/Maximum Query)


     Range Minimum/Maximum Query

    别名S(Sparse)T(Table)直译稀疏表表

    这是个什么东西?可以理解为一种题型。用来求某个区间内的最大值或最小值,通常用在需要多次询问一些区间的最值的问题中。隶属于动规DP

    这主要针对于区间内最大值或最小值,不需要修改的题型。需要修改的话,请右转线段树。

    引题描述

     输入N个数和M次询问,每次询问一个区间[L,R],求第L个数到R个数之间的最大值。 

    题析

    用A[1..N]表示一组数,F[I,J]表示从A[I]到A[I+2^J-1]这个范围内的最大值,也就是以A[I]为起点连续2^J个数的最大值,由于元素个数为2^J个,所以从中间平均分成两部分,每一部分的元素个数刚好为2^(J-1)个,如下图:

    整个区间的最大值一定是左右两部分最大值的较大值,满足动态规划的最优原理
    状态转移方程:

    F[I,J]=max(F[I,J-1],F[I+2^(J-1),J-1])
    边界条件为F[I,0]=A[I]

    1<=j<=floor(log2(n))

    1<=i<=n-2^i+1

    这样就有效防止了i的溢出,j的向下取整也保证了其不会超出区间最右端的范围
    这样就可以在O(NlgN)的时间复杂度内预处理F数组。

    题目中的ShowTime

    高度平衡 Balanced Lineup  USACO 2007 January Silver 

    题来

    板子题不绕弯,直接上代码了

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int MAXN=50010;
    int n,q;
    int Height[MAXN];
    int RMaxQ[MAXN][20];
    int RMinQ[MAXN][20];
    int main(){
        scanf("%d%d",&n,&q);
        for(int i=1;i<=n;i++){
            scanf("%d",&Height[i]);
            RMinQ[i][0]=Height[i];
            RMaxQ[i][0]=Height[i];
        }
        for(int j=1;j<=floor(log2(n));j++){
            for(int i=1;i<=(n-(1<<j)+1);i++){
                RMinQ[i][j]=min(RMinQ[i][j-1],RMinQ[i+(1<<(j-1))][j-1]);
                RMaxQ[i][j]=max(RMaxQ[i][j-1],RMaxQ[i+(1<<(j-1))][j-1]);
            }
        }
        int a,b,k;
        int a1,a2;
        for(int i=1;i<=q;i++){
            scanf("%d%d",&a,&b);
            k=floor(log2(b-a+1));
            a1=min(RMinQ[a][k],RMinQ[b-(1<<k)+1][k]);
            a2=max(RMaxQ[a][k],RMaxQ[b-(1<<k)+1][k]);
            printf("%d
    ",a2-a1);
        }
    }    

     奶牛探洞  USACO OPEN2004 

    第二道板子题,稍作修改就行了。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int MAXN=26000;
    int n,q;
    int Width[MAXN];
    int RMQ[MAXN][20];
    int main(){
        scanf("%d%d",&n,&q);
        for(int i=1;i<=n;i++){
            scanf("%d",&Width[i]);
            RMQ[i][0]=Width[i];
        }
        for(int j=1;j<=floor(log2(n));j++){
            for(int i=1;i<=(n-(1<<j)+1);i++){
                RMQ[i][j]=min(RMQ[i][j-1],RMQ[i+(1<<(j-1))][j-1]);
                
            }
        }
        int a,b;
        for(int i=1;i<=q;i++){
            scanf("%d%d",&a,&b);
            int k=floor(log2(b-a+1));
            cout<<min(RMQ[a][k],RMQ[b-(1<<k)+1][k])<<endl;
        }
    }
  • 相关阅读:
    .NET性能调优之三:YSlow相关规则的调优工具和方法
    .NET性能调优之二:使用Visual Studio进行代码度量
    OSPF的常见前7类LSA详解
    Packet Tracer 5.3搭建DNS服务器
    中型网络中网络冗余设计的要领
    GNS3模拟器如何保存配置文件
    CCNA相当综合的实验1
    GNS模拟器中支持的模块说明
    典型配置:H3C基于AP限制接入客户端数量
    破解H3C交换机密码的方法
  • 原文地址:https://www.cnblogs.com/Uninstalllingyi/p/10691797.html
Copyright © 2020-2023  润新知