zoukankan      html  css  js  c++  java
  • 倍增算法1

    首先用倍增法解决一道求区间最大值问题,算是倍增的入门了。

    其实也算是一种dp,不过大家把这个二维dp数组叫做ST表。

    ST表数组:f[i][j],表示区间【i,i+2j-1】的最大值。这个区间的大小是2j个数。

    ST表的初始化:f[i][0]=a[i]。(显然这是区间大小为1的时候)

    ST表的递推过程:

    1,由区间大小为1的项转移得到区间大小为21的项

    2,由区间为21的项转移得到区间为22的项

    3,由区间为22的项转移得到区间为23的项

    。。。

    这就是倍增的由来了吧。

    这个递推过程的代码:

    1 void RMQ(int N){
    2     for(int j=1;(1<<j)<=N;j++)    
    3     for(int i=1;i<=N;i++)
    4         if(i+(1<<j)-1<=N)
    5          f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]); 
    6 }

    经过处理后,访问一段长区间便能利用事先处理好的数据得出答案

    比如询问最大值的一项处理技术:

    因为区间的长度为j-i+1,所以可以取k=log2(j-i+1)。

    则RMQ(A,i,j)=max(f[i][k],f[j-2^k+1][k])。

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<cmath>
     6 using namespace std;
     7 int a[100001],f[100001][20];
     8 
     9 void RMQ(int N){
    10     for(int j=1;(1<<j)<=N;j++)    
    11     for(int i=1;i<=N;i++)
    12         if(i+(1<<j)-1<=N)
    13          f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]); 
    14 }
    15 int main(){
    16     int N,M;
    17     int tt;
    18     cin>>tt;
    19     while(tt--) 
    20     {
    21         cin>>N;
    22     for(int i=1;i<=N;i++) cin>>a[i];
    23     for(int i=1;i<=N;i++) f[i][0]=a[i];
    24     RMQ(N); 
    25     cin>>M;
    26     while(M--){
    27         int l,r;
    28         cin>>l>>r;
    29          int k=(int)(log((double)(r-l+1))/log(2.0)); 
    30         printf("%d
    ",max(f[l][k],f[r-(1<<k)+1][k]));
    31     }
    32     }
    33     return 0;
    34 }
  • 相关阅读:
    centos 8 安装zabbix4.5
    python调用钉钉机器人发送消息
    基于docker-compose部署Prometheus + Grafana监控系统
    在阿里云上单机部署k8s1.18
    python3使用email模块发送邮件
    mongodb mysql es数据迁移
    Dockerfile详解
    docker-compose部署zabbix5.0
    centos8.1部署gitlab+jenkins
    基于docker-compose部署jumpserver
  • 原文地址:https://www.cnblogs.com/lnu161403214/p/9255533.html
Copyright © 2011-2022 走看看