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\n",MAX);
    }
    return 0;
}

 

posted @ 2016-08-21 16:55  樱花庄的龙之介大人  阅读(201)  评论(0编辑  收藏  举报