• csu 1553(RMQ+尺取法)


    1553: Good subsequence

    Time Limit: 2 Sec  Memory Limit: 256 MB
    Submit: 794  Solved: 287
    [Submit][Status][Web Board]

    Description

    Give you a sequence of n numbers, and a number k you should find the max length of Good subsequence. Good subsequence is a continuous subsequence of the given sequence and its maximum value - minimum value<=k. For example n=5, k=2, the sequence ={5, 4, 2, 3, 1}. The answer is 3, the good subsequence are {4, 2, 3} or {2, 3, 1}.

    Input

    There are several test cases.
    Each test case contains two line. the first line are two numbers indicates n and k (1<=n<=10,000, 1<=k<=1,000,000,000). The second line give the sequence of n numbers a[i] (1<=i<=n, 1<=a[i]<=1,000,000,000).
    The input will finish with the end of file.

    Output

    For each the case, output one integer indicates the answer.

    Sample Input

    5 2
    5 4 2 3 1
    1 1
    1

    Sample Output

    3
    1


    题意:在区间内找一段长度最大的子区间满足子区间的最大值 - 子区间的最小值 <=k ,输出最大值。
    题解:尺取法扫一遍就可以得到了,区间最大最小用RMQ或者线段树都可以。
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    using namespace std;
    #define N 10010
    
    int a[N];
    int max_dp[N][20];
    int min_dp[N][20];
    
    void init_MAX_RMQ(int n){
        for(int i=1;i<=n;i++) max_dp[i][0]=a[i];
        for(int j=1;(1<<j)<=n;j++){
            for(int i=1;i<=n-(1<<j)+1;i++){
                max_dp[i][j] = max(max_dp[i][j-1],max_dp[i+(1<<(j-1))][j-1]);
            }
        }
    }
    int MAX_RMQ(int a,int b){
        int k = (int)(log(b-a+1.0)/log(2.0));
        return max(max_dp[a][k],max_dp[b-(1<<k)+1][k]);
    }
    void init_MIN_RMQ(int n){
        for(int i=1;i<=n;i++) min_dp[i][0]=a[i];
        for(int j=1;(1<<j)<=n;j++){
            for(int i=1;i<=n-(1<<j)+1;i++){
                min_dp[i][j] = min(min_dp[i][j-1],min_dp[i+(1<<(j-1))][j-1]);
            }
        }
    }
    int MIN_RMQ(int a,int b){
        int k = (int)(log(b-a+1.0)/log(2.0));
        return min(min_dp[a][k],min_dp[b-(1<<k)+1][k]);
    }
    int main()
    {
        int n,k;
        while(scanf("%d%d",&n,&k)!=EOF){
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
            }
            init_MAX_RMQ(n);
            init_MIN_RMQ(n);
            int MAX = -1;
            int maxv =a[1], minv = a[1];
            int l = 1,r = 1;
            while(l<=n){
                while(r<=n){
                    maxv = MAX_RMQ(l,r);
                    minv = MIN_RMQ(l,r);
                    if(maxv-minv>k) break;
                    MAX = max(r-l+1,MAX);
                    r++;
                }
                l++;
                maxv = MAX_RMQ(l,r);
                minv = MIN_RMQ(l,r);
            }
            printf("%d
    ",MAX);
        }
        return 0;
    }
  • 相关阅读:
    4.9 省选模拟赛 圆圈游戏 树形dp set优化建图
    C#异步编程の-------异步编程模型(APM)
    C#异步编程の----Threadpool( 线程池)
    C#の----Func,Action,predicate在WPF中的应用
    C#常见委托のdelegate定义,Func,Action,Predicate总结
    c++のmap的遍历
    C#深度学习の----深拷贝与浅拷贝
    NSIS学习记录の----查找注册表某个键是否存在
    WPFの操作文件浏览框几种方式
    C#Url处理类
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5793036.html
Copyright © 2020-2023  润新知