zoukankan      html  css  js  c++  java
  • poj 3264 Balanced Lineup

    福建农林大学 FAFU poj也有一题和这题差不多的,可以去尝试看看

    http://acm.fafu.edu.cn/problem.php?id=1272

    RMQ poj 3264 Balanced Lineup
    //poj 3264 Balanced Lineup
    //RMQ
    //用RMQ求出最大值和最小值相减即可,具体看一下代码
    //学RMQ可以看着个博客http://blog.csdn.net/ice2013/article/details/7545143
    //写的挺不错的
    
    //预处理,
    //动归求出dp_max[i][j]和dp_min[i][j],dp表示从i开始的2^j个数中的最值,
    //2^j一定是偶数,所以把它分为 [i,i+2^(j-1)-1]和[i+2^(j-1), i+2^j -1]这两个区间,
    //则dp[i][j]即从这两个区间得出,即dp[i][j] = max(dp[i][1<<(j-1)], dp[i+(1<<(j-1)][j-1])
    //询问[a,b]时先求出tmp = log(b-a+1)/log(2.0)
    //然后求max(dp[a][tmp], dp[b-(1<<tmp) + 1][tmp])
    
    //注意:动归过程中要注意i+(1<<j)-1 <= n,询问时记得
    //dp[b - (1<<tmp) + 1][tmp]前面那个要加 1
    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    #include <algorithm>
    
    using namespace std;
    
    #define comein freopen("in.txt", "r", stdin);
    #define N 50005
    #define INF 1<<30
    #define eps 1e-5
    
    int dp_max[N][20], dp_min[N][20];
    
    
    void init(int n_cow)
    {                   //n_cow可以表示成2 的几次方,换底公式
        int index = log(n_cow * 1.0) / log(2.0);
        for(int j = 1; j <= index; ++j)
        {       //i ~ i+(1<<j)-1 之间有 i+(1<<j)-1 - i + 1 即 1<<j个数,包括i
            for(int i = 1; i + (1<<j) - 1 <= n_cow; ++i)
            {   //dp[i][j]表示从i起 2^j个数,i ~ i+(2^j)-1 这个区间的最值
                //如dp[3][2] 表示 3 ~ 6,从3起有2^2个数,因为这样区间长度都为偶数个
                //所以把 区间分为 i~ i+(2^j-1)-1 和 i+(2^j-1)-1 ~ i+(2^j)-1这两个区间
                //长度都为 2^(j-1) 个数, 所以dp[i][j]的记录的最值即为dp[i][j-1] 和
                //dp[i + (2^(j-1))][j-1]这两个部分的最值
                dp_max[i][j] = max(dp_max[i][(j-1)], dp_max[i + (1<<(j-1))][j-1]);
                dp_min[i][j] = min(dp_min[i][(j-1)], dp_min[i + (1<<(j-1))][j-1]);
            }
        }
    }
    
    int RMQ(int from, int to)
    {   //假如我们需要查询的区间为(i,j),
        //因为这个区间的长度为j - i + 1,所以我们可以取k=log2( j - i + 1),
        //则有:RMQ(A, i, j)=max{F[i , k], F[ j - 2 ^ k + 1, k]}。
        int index = log((to - from + 1) * 1.0) / log(2.0);
        int mx = max(dp_max[from][index], dp_max[to - (1<<index) + 1 ][index]);
        int mn = min(dp_min[from][index], dp_min[to - (1<<index) + 1 ][index]);
        return mx - mn;
    }
    
    int main()
    {
        int n_cow, n_query;
        while(scanf("%d%d", &n_cow, &n_query) != EOF)
        {
            for(int i = 1; i <= n_cow; ++i)
            {
                int heigh;
                scanf("%d", &heigh);
                //从第i个起的 2^0 个数中的最大值和最小值
                dp_max[i][0] = dp_min[i][0] = heigh;
            }
            init(n_cow);
            while(n_query--)
            {
                int from, to;
                scanf("%d%d", &from, &to);
                if(from > to)
                {
                    from ^= to;
                    to ^= from;
                    from ^= to;
                }
                printf("%d\n", RMQ(from, to));
            }
        }
        return 0;
    }
  • 相关阅读:
    Mvc+三层(批量添加、删除、修改)
    js中判断复选款是否选中
    EF的优缺点
    Git tricks: Unstaging files
    Using Git Submodules
    English Learning
    wix xslt for adding node
    The breakpoint will not currently be hit. No symbols have been loaded for this document."
    Use XSLT in wix
    mfc110ud.dll not found
  • 原文地址:https://www.cnblogs.com/gabo/p/2606619.html
Copyright © 2011-2022 走看看