zoukankan      html  css  js  c++  java
  • RMQ算法

    RMQ (Range Minimum/Maximum Query)问题是指:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j里的最小(大)值,也就是说,RMQ问题是指求区间最值的问题。

    通常来说RMQ算法的实现有两种方法

    1、线段树实现。这里不讲,可以参考http://www.cnblogs.com/ISGuXing/articles/7215486.html

    时间复杂度大概是O(n)-O(qlogn)

    2、第二种方法就是ST算法

    预处理时间复杂度为O(nlogn) 查询的时间为O(1);

    适合用于比较多的数据的查询。

    该算法的核心其实就是动态规划。(ps:再一次说明动态规划思想的重要性!)

    在这篇随笔中笔者就不讲ST算法具体实现是怎么样的,贴上一个比较好的文章http://blog.csdn.net/niushuai666/article/details/6624672

    在这篇随笔主要讲数组F[ n] [20]含义是什么,为什么这样做。

    F[i, j]表示从第i个数起连续2^j个数中的最大值。(DP的状态)

    那么当j=0的时候也就是区间只有i 它本身的时候最值肯定是其本身。

    这是初始化。

    那么状态转移方程就能出来了F[i, j] =max( F[ i, j-1] ,F[i+(1<<(j-1)) , j-1] )

    想一想将一个区间二分是不是这个样子。

    既然这也出来了,那么查询就很清晰了

    假如我们需要查询的区间为(i,j),那么我们需要找到覆盖这个闭区间(左边界取i,右边界取j)的最小幂(可以重复,比如查询5,6,7,8,9,我们可以查询5678和6789)。

    因为这个区间的长度为j - i + 1,所以我们可以取k=log2( j - i + 1),则有:RMQ(A, i, j)=max{F[i , k], F[ j - 2 ^ k + 1, k]}。

    举例说明,要求区间[2,8]的最大值,k = log2(8 - 2 + 1)= 2,即求max(F[2, 2],F[8 - 2 ^ 2 + 1, 2]) = max(F[2, 2],F[5, 2]);

    在这里我们也需要注意一个地方,就是<<运算符和+-运算符的优先级。

    比如这个表达式:5 - 1 << 2是多少?

    答案是:4 * 2 * 2 = 16。所以我们要写成5 - (1 << 2)才是5-1 * 2 * 2 = 1。

    ps:部分内容转自上面的那份博客。

  • 相关阅读:
    Linux在线或者离线安装gitlab
    Linux如何安装rpm文件
    使用docker run启动并进入一个容器
    docker导入导出镜像
    Mycat学习笔记一
    Mysql源码安装过程中可能碰到的问题
    当idea的maven项目没有.iml文件导致打开失败时
    从Vue.js窥探前端行业
    CSS 的overflow:hidden 属性详细解释
    win7系统Myeclipse下切换SVN用户
  • 原文地址:https://www.cnblogs.com/ISGuXing/p/7237169.html
Copyright © 2011-2022 走看看