原理很简单,思想很重要~~~
一维RMQ:
/*一维RMQ*/
const int MAXN = 1010;
int elem[MAXN];
int dp[MAXN][15];
int n;
void RMQ_Init()
{
int i, j;
for(i = 1; i <= n; ++i)
dp[i][0] = elem[i];
for(j = 1; (1<<j) <= n; ++j)
{
for(i = 1; i + (1<<j) - 1 <= n; ++i)
{
dp[i][j] = min(dp[i][j-1], dp[i+(1<<(j-1))][j-1]);
}
}
return ;
}
int RMQ_Query(int l, int r)
{
int k = (int)(log(r-l+1.0)/log(2.0));
return min(dp[l][k], dp[r-(1<<k)+1][k]);
}
二维RMQ:
const int MAXN = 110;
int elem[MAXN][MAXN];
int dp[MAXN][MAXN][10][10];
int n, m;
void RMQ_Init()
{
int row, col, i, j;
for(row = 1; row <= n; ++row)
{
for(col = 1; col <= m; ++col)
{
dp[row][col][0][0] = elem[row][col];
}
}
for(i = 0; (1<<i) <= n; ++i)
{
for(j = 0; (1<<j) <= m; ++j)
{
if(i == 0 && j == 0) continue;
for(row = 1; row + (1<<i) - 1 <= n; ++row)
{
for(col = 1; col + (1<<j) - 1 <= m; ++col)
{
if(i == 0)
{
dp[row][col][i][j] = min(dp[row][col][i][j-1], dp[row][col+(1<<(j-1))][i][j-1]);
}
else if(j == 0)
{
dp[row][col][i][j] = min(dp[row][col][i-1][j], dp[row+(1<<(i-1))][col][i-1][j]);
}
else
{
dp[row][col][i][j] = min(min(dp[row][col][i-1][j-1], dp[row][col+(1<<(j-1))][i-1][j-1]),\
min(dp[row+(1<<(i-1))][col][i-1][j-1], dp[row+(1<<(i-1))][col+(1<<(j-1))][i-1][j-1]));
}
}
}
}
}
}
int RMQ_Query(int x1, int y1, int x2, int y2)
{
int kx = (int)(log(x2-x1+1.0)/log(2.0));
int ky = (int)(log(y2-y1+1.0)/log(2.0));
return min(min(dp[x1][y1][kx][ky], dp[x2-(1<<kx)+1][y1][kx][ky]), min(dp[x1][y2-(1<<ky)+1][kx][ky], \
dp[x2-(1<<kx)+1][y2-(1<<ky)+1][kx][ky]));
}