RMQ问题

原理很简单,思想很重要~~~


一维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]));
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值