• The Water Problem HDU-5443


    题目:给定n个数,q个询问,每个询问包含lr(l和 r代表区间),求区间[l,r]内的最大值。

    RMQ问题:RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于一个长度N的数组,在多次询问中,每次都以O(1)的时间得到区间[a, b]的最大值或最小值。

    ST ( Sparse Table ) 算法:ST(Sparse Table)算法是一个非常有名的在线处理RMQ问题的算法,它可以在O(nlogn)时间内进行预处理,然后在O(1)时间内回答每个查询。其思想就是保存以i为起点的某段数据的最小值。

    在线算法:在线算法有个预处理过程,预处理数据之后,能够更快速的处理每次请求的结果,但是会有一个相对长一点的预处理过程。

    离线算法:所谓离线算法只是在来了非常多的请求之后,一次性处理多个请求,能够不依赖于预处理数据,却能一次完成多个请求的结果。

    解题思路:DP思想,首先要记录每步的状态。

    最初始状态:F[0, 0] = A[0]; F[1,0] = A[1]; F[2,0] = A[2]; 意思是说每单个元素的最大值都是自己(因为只有一个元素)

    之后:F[i, j] = max(F[i, j-1], F[i+2^(j-1)][j-1]);

    假如查询的区间是奇数个,头尾分开。

    首先明确区间的长度为j - i + 1

    可以取k=log2( j - i + 1) //要能够两个F加在一起能够覆盖整个区间

    RMQ(A, i, j)=max{F[i , k], F[ j - 2 ^ k + 1, k]}

    代码实现:

     1 #include<iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 #define MAXARR 1005
     7 int T, n, q;
     8 int l, r;
     9 int maxNum[MAXARR][32];
    10 //int minNum[MAXARR][32];
    11 void RMQ(int n) {
    12     for (int j = 1; j < 31; j++) {
    13         for (int i = 0; i < n; i++) {
    14             if (i + (1 << j) - 1 < n) {
    15                 maxNum[i][j] = max(maxNum[i][j - 1], maxNum[i + (1 << (j - 1))][j - 1]);
    16             //    minNum[i][j] = min(minNum[i][j - 1], minNum[i + (1 << (j - 1))][j - 1]);
    17             }
    18         }
    19     }
    20 }
    21 int main() {
    22     cin >> T;
    23     while (T--) {
    24         memset(maxNum, 0, sizeof(maxNum));
    25     //    memset(minNum, 0, sizeof(minNum));
    26         cin >> n;
    27         //初始化第一列
    28         for (int i = 0; i < n; i++) {
    29             cin >> maxNum[i][0];
    30         //    minNum[i][0] = maxNum[i][0];
    31         }
    32         RMQ(n);
    33         cin >> q;
    34         for (int i = 0; i < q; i++) {
    35             cin >> l >> r;
    36             int k = log2(r - l + 1);
    37             cout << max(maxNum[l - 1][k], maxNum[r - 1 - (int)(1 << k) + 1][k]) << endl;  //区间根据下标要减1
    38         //    cout << min(minNum[l - 1][k], minNum[r - 1 - (int)(1 << k) + 1][k]) << endl;
    39         }
    40     }
    41     return 0;
    42 }
  • 相关阅读:
    java内存泄露
    hbase java api
    配置CRT远程登录
    kafka分区消费模型
    JAVA内存区域
    JVM分代和垃圾回收
    spring中bean的作用域
    分布式RPC
    session共享
    ZooKeeper实现分布式session
  • 原文地址:https://www.cnblogs.com/0211ji/p/13158201.html
Copyright © 2020-2023  润新知