poj_3264 Balanced Lineup 用ST算法解RMQ问题
DP的思想:从i到i+2^(j-1)-1为一段,i+2^(j-1)到i+2^j-1为一段(长度都为2^(j-1)),状态转移方程为:
F[i,j]=max(F[i,j-1],F[i+2^(j-i),j-1])
最大值 f[i,j]=max(f[i,j-1],f[i+2^(j-1),j-1]);
最小值 f[i,j]=min(f[i,j-1],f[i+2^(j-1),j-1]);
最大值 f[i,j]=max(f[i,j-1],f[i+2^(j-1),j-1]);
最小值 f[i,j]=min(f[i,j-1],f[i+2^(j-1),j-1]);
View Code
#include<cstdio> #include<cstring> #include<iostream> #include<cmath> using namespace std; const int N = 50001; #define Max(a,b) a>b?a:b #define Min(a,b) a<b?a:b int h[N],maxx[N][16],minx[N][16]; int n,m; void Init() { for(int i=1;i<=n;i++) maxx[i][0]=minx[i][0]=h[i]; int k=floor(log((double)n)/log(2.0)); for(int i=1;i<=k;i++) for(int j=n;j>=1;j--) { int jj=j+(1<<(i-1)); maxx[j][i]=maxx[j][i-1]; minx[j][i]=minx[j][i-1]; if(jj<=n) { maxx[j][i]=Max(maxx[j][i-1],maxx[jj][i-1]); minx[j][i]=Min(minx[j][i-1],minx[jj][i-1]); } } } int rmq(int l,int r) { int k=floor(log((double)(r-l+1))/log(2.0)); int mx=Max(maxx[l][k],maxx[r-(1<<k)+1][k]); int mi=Min(minx[l][k],minx[r-(1<<k)+1][k]); return mx-mi; } int main() { int l,r; while(~scanf("%d%d",&n,&m)) { for(int i=1;i<=n;i++) scanf("%d",&h[i]); Init(); for(int i=0;i<m;i++) { scanf("%d%d",&l,&r); printf("%d\n",rmq(l,r)); } } return 0; }

浙公网安备 33010602011771号