zoukankan      html  css  js  c++  java
  • RMQ(dp)

    我一开始是不知道有这么个东西,但是由于最近在学习后缀数组,碰到一道题需要用到后缀数组+RMQ解决的所以不得不学习了。

    原理:用A[1...n]表示一组数,dp[i][j]表示从A[i]到A[i+2^j-1]这个范围内的最大值或者最小值也就是以A[i]为起点连续2^j个数的最大值或者最小值,由于元素个数为2^j个,所以从中间平均分成两部分,每一部分的元素个数刚好为2^(j-1)个。 整个区间的最大值一定是左右两部分最大值的较大值,满足动态规划的最优原理。

    状态转移方程为:dp[i][j]=min(dp[i][j-1],dp[i+2^(j-1)][j-1]);边界条件为:dp[i][0]=a[i]; 这样就可以在O(NlgN)的时间复杂度内预处理dp数组了。

    预处理dp数组:

     for(int i=1;i<=n;i++)

       dp[i,0]:=a[i];
     
    for(int j=1;(1<<j)<=n;j++)
    {
       for(int i=1;i+(1<<j)-1<=n;j++)
         dp[i,j]=max(dp[i,j-1],dp[i+1<<(j-1),j-1]); 
    };
    然后到了查询的阶段了,由于我们预处理了dp数组,所以我们在查询的时候时间是很快的!!
     
    对于询问[L,R],求出最大的x,满足2^x<=R-L+1,即x=ln(R-L+1)/ln(2) ;[L,R]=[L,L+2^x-1] ∪[R+1-2^x,R],两个子区间元素个数都是2^x个,如图
     
    ans(L,R)=max(dp[L,x],dp[R+1-2^x,x])
     
     
     
  • 相关阅读:
    java_hibernate 框架4
    java_hibernate 框架3
    java 基础 动态代理
    java_hibernate 框架2
    nginx配置反向代理实现负载均衡 小记
    mysql报错2059
    docker安装php容器小记
    docker安装nginx容器小记
    linux php添加pdo_mysql扩展
    linux php添加openssl扩展
  • 原文地址:https://www.cnblogs.com/jiangjing/p/3249639.html
Copyright © 2011-2022 走看看