poj3264(RMQ果题)

我的实习就这么定下来了,下周一就出发了,估计是做数据挖掘的项目了,往研发努力这么久,最后第一份实习竟然是数据挖掘,出自数学系的感觉总是怪怪的,不过也是很高兴的。不过我所属部门还是研发部,用的是python,作为一个刚刚会写基本的程序的菜鸟,知道两个月后会怎么样呢?希望公司有大神赐教。实习后估计会更累,但是我还是会每天刷题,尽早记录!

另外值得高兴的是,我的队伍凑出来啦,这次引入了一个女生呢!!广大的ACMer是不是很羡慕?还有,实习宿舍有空调呢,我们学校都木有!!每天都热得要死。实习公司配的电脑,我想要Linux的!╮(╯▽╰)╭,没可能的节奏,作为一个linux脑残粉,没有命令要死啊..我的各种shell脚本都不能用咯这个节奏~

回归正题:今天做的不是纯粹的DP了(实际还是DP。。)做的是RMQ呢。

先解释一下RMQ吧,大神们就忽略我的解说吧:RMQ的意思就是range max/min query,就是区间最值查询,这类问题姿势好想很多,今天用的是ST算法,大概的意思就是动态规划,以求最大值为例子啦,Max[i][j],代表的是从第i个开始,到第2^j个中最大的,显然Max[i][0]=a[i],即那个数本身。状态转移方程为:

                        Max[i][j]=max(Max[i][j-1],Max[i+(1<<(j-1))][j-1]),

意思很明显啦,就是前半段和后半段的最大值,[i ,2^(j-1)], [2^(j-1),j]的最大值.

poj3264的题目意思就是,一群牛,多次区间查询,问最高的和最矮的差。

/***********************************************************
	> OS     : Linux 3.2.0-60-generic #91-Ubuntu
	> Author : yaolong
	> Mail   : dengyaolong@yeah.net 
	> Time   : 2014年06月05日 星期四 07:37:36
 **********************************************************/
#include<iostream>
#include<cstdio>
#include<string>
#include<cmath>
#include<cstring>
using namespace std;
#define MAXN 100000
#define MAXE 100
int h[MAXN],mmax[MAXN][MAXE],mmin[MAXN][MAXE];
int N,Q;
int L,R;
void RMQ_ST(){
    for(int i=1;i<=N;i++){
        mmax[i][0]=h[i];
        mmin[i][0]=h[i];
    }
    int end_j=log(N+0.0)/log(2.0);
    int end_i;
    for(int j=1;j<=end_j;j++){
        end_i=N+1-(1<<j);
        for(int i=1;i<=end_i;i++){
            mmax[i][j]=max(mmax[i][j-1],mmax[i+(1<<(j-1))][j-1]);
            mmin[i][j]=min(mmin[i][j-1],mmin[i+(1<<(j-1))][j-1]);
        }
    }
}
int QueryMax(int L,int R){
   
    int k=log(R-L+1.0)/log(2.0);
    return max(mmax[L][k],mmax[R-(1<<k)+1][k]);
}
int QueryMin(int L,int R){
   
    int k=log(R-L+1.0)/log(2.0);
    return min(mmin[L][k],mmin[R-(1<<k)+1][k]);
}
int main(){
    while(scanf("%d%d",&N,&Q)!=EOF){
  
        for(int i=1;i<=N;i++){
            scanf("%d",&h[i]);
        }
        
        RMQ_ST();
        for(int i=0;i<Q;i++){
            scanf("%d%d",&L,&R);
            printf("%d\n",QueryMax(L,R)-QueryMin(L,R));
        }
   }

return 0;
}




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值