谈谈我对RMQ问题的ST算法理解

1、首先要了解一下RMQ的概念:

  RMQ (Range Minimum/Maximum Query)问题是指:

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

2、求取最值的方法

  (1)暴力,时间复杂度O(n^2)

  (2)ST表,首先进行预处理O(nlogn)之后单次查询O(log(r-l))

3、分析ST方法

 

   核心代码块理解:dp【i,j】表示从第i个数开始连续2^j个数中的最值

/*
以求最大值为例 
*/
const int maxn = 105;

int dp[maxn][len];// len的条件:2^len > maxn 即可
int a[maxn];
int n; //数组的长度 
void rmq_init()
{    
    for(int i = 1; i <= n; i++)
    {
        dp[i][0] = a[i];//从第i个数开始之后的2^0 = 1个数的最值就是其本身 
    }
     
    for(int j = 1; (1<<j) <= n; j++) //往后的长度不能超n 
    {
        for(int i = 1; (i+(1<<j)-1) <= n; i++) //第i个数之后的2^j个数,其长度不能超n 
        {
            dp[i][j] = max(dp[i][j-1], dp[i+(1<<(j-1))][j-1]);
            /*重点解释一下这条语句:
            从第i个数开始,在2^j个数中求最值,可以将2^j范围拆成两个2^(j-1) 
             即第一段:a[i]~~a[i+(2^(j-1))]
               第二段:a[i+(2^(j-1)]~a[i+2^j]
             */ 
        } 
    }
    
}

int rmq_max(int l, int r)
{
int k = 0; //k就是要划分的一半区间的幂级数 while( (1<<(k+1)) <= r - l + 1) { k++; } return max(dp[l][k], dp[r-(1<<k)+1][k]); }

安利一篇博客,讲的很是透彻

转:http://blog.csdn.net/aitangyong/article/details/26940155

转载于:https://www.cnblogs.com/mcgrady_ww/p/8576656.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值