**如下:
bin[0]=1;
for(int i=1;i<20;i++)
bin[i]=bin[i-1]*2;//bin[i]表示2的i次方
log[0]=-1;
for(int i=1;i<=200000;i++)
log[i]=log[i/2]+1;//log[i]表示log(i)
for(int i=1;i<=n;i++)
mn[0][i]=a[i];//顯然i到i+2^0-1就i乙個位置,那麼最小值等於自己本身的值
for(int i=1;i<=log[n];i++)
for(int j=1;j<=n;j++)
if(j+bin[i]-1<=n)
mn[i][j]=min(mn[i-1][j],mn[i-1][j+bin[i-1]]);//狀態繼承
搞定了初始化之後,剩下的就是來查詢了。
首先明白乙個定理:
a>=2^log(a)>a/2
這個很簡單,因為log(a)表示小於等於a的2的最大幾次方。
比如說lon(3)=1,log(4)=2,log(5)=2,log(6)=2,log(7)=2,log(8)=3,log(9)=3…….
那麼我們要查詢x到y的最小值。
設len=y-x+1,t=log(len)
根據上面的定理:len>=2^t>len/2
從位置上來說,x+2^t越過了x到y的中間!
因為位置過了一半
所以x到y的最小值可以表示為min(從x往後2^t的最小值,從y往前2^t的最小值)
前面的狀態表示為mn[t][x]
設後面(從y往前2^t的最小值)的初始位置是k,
那麼k+2^t-1=y,所以k=y-2^t+1
所以後面的狀態表示為mn[t][y-2^t+1]
所以x到y的最小值表示為min(mn[t][x],mn[t][y-2^t+1]),所以查詢時間複雜度是o(1)
**實現:
int t=log[y-x+1];
printf("%d\n",min(mn[t][x],mn[t][y-bin[t]+1]));
求解區間最值的ST演算法
作用 st演算法是用來求解給定區間rmq的最值,本文以最小值為例 舉例 給出一陣列a 0 5 則區間 2,5 之間的最值為1。1 離線預處理 運用dp思想,用於求解區間最值,並儲存到乙個二維陣列中。具體解釋 1 離線預處理 st演算法使用dp思想求解區間最值,貌似屬於區間動態規劃,不過區間在增加時,...
st演算法模板(區間最值)
f 1,0 表示第1個數起,長度為2 0 1的最大值,其實就是3這個數。f 1,2 5,f 1,3 8,f 2,0 2,f 2,1 4 從這裡可以看出f i,0 其實就等於a i 這樣,dp的狀態 初值都已經有了,剩下的就是狀態轉移方程。我們把f i,j j 1 平均分成兩段 因為j 1時,f i,...
ST表(RMQ問題 區間最值查詢
3 2 4 5 6 8 1 2 9 7 預處理,用dp解決。設a i 是要求區間最值的數列,dp i,j 表示從第i個數起連續2 j個數中的最大值。dp 1,0 表示第1個數起,長度為2 0 1的最大值,其實就是3這個數。dp 1,2 5,dp 1,3 8,dp 2,0 2,dp 2,1 4 可以看...