RMQ

来源:互联网 发布:中国移动浙江问问网络 编辑:程序博客网 时间:2024/04/29 13:35

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

解决方法ST算法(实质上是动态规划):

设数组为A,f[i][j]其中i表示数组A以i为起点,长度为2^j的范围内的最值,除了j=0长度为1外,其余j>=1长度肯定为偶数,现在进入算法流程:比如要求得f[i][j](j>=1)的最值,是否可以把f[i][j]分为两份再进行比较,max(f[i][j-1],f[i+(1<<(j-1))][j-1])或者(min(f[i][j-1],f[i+(1<<(j-1))][j-1])),原理如图:

根据这样可以得出状态方程为: f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);

ST算法代码:

#define max(a,b) a>b?a:bint f[10000][20]={0};void RMQ(int *A,int N)//N为数组A长度{int k=(int)(log(N)/log(2.0));int i,j;for(i=0;i<N;i++)f[i][0]=A[i];//初始化for(j=1;j<=K;j++)for(i=0;i<=N-(1<<j);i++)f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);}

查询在A[i......j]的最值代码:

int RMQ_M(int i,int j){int k=(int)(log(j-i+1)/log(2.0));return max(f[i][k],f[j-(1<<k)+1][k]);}
比如求A[1....5]的最值:

可以这样求max(f[1][2],f[2][5])




0 0