hdu3530 Subsequence 单调队列

来源:互联网 发布:职工信息管理系统c语言 编辑:程序博客网 时间:2024/06/09 03:14

Subsequence

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3996    Accepted Submission(s): 1309


Problem Description
There is a sequence of integers. Your task is to find the longest subsequence that satisfies the following condition: the difference between the maximum element and the minimum element of the subsequence is no smaller than m and no larger than k.
 

Input
There are multiple test cases.
For each test case, the first line has three integers, n, m and k. n is the length of the sequence and is in the range [1, 100000]. m and k are in the range [0, 1000000]. The second line has n integers, which are all in the range [0, 1000000].
Proceed to the end of file.
 

Output
For each test case, print the length of the subsequence on a single line.
 

Sample Input
5 0 01 1 1 1 15 0 31 2 3 4 5
 

Sample Output
54
 

Source
2010 ACM-ICPC Multi-University Training Contest(10)——Host by HEU
 

Recommend
zhengfeng   |   We have carefully selected several similar problems for you:  3535 3529 3528 3527 3531 
 


题意:求一个最长子序列,序列最大值与最小值的差d, m<=d<=k。

思路:用两个单调队列维护最大值、最小值,从左往右扫一遍。当队首元素差大于k,删除队首元素,我们需要删除的应该是两个队首元素数组下标小的那个。我们这样考虑,假设当前扫到i,答案ans=max(ans,i-max(que1[head1].index,que2[head2].index)+1),如果我们删除下标大的那个队首元素,那么对应的队列必然要head++,即满足条件的下标在变大,那么max(que1[head1].index,que2[head2].index)必然也跟着增大,不能满足max(que1[head1].index,que2[head2].index)尽可能小,而删除下标小的队首元素,可以在max(que1[head1].index,que2[head2].index)尽可能小的情况下满足m<=d<=k。详见程序:

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAXN=100000+100;int n,m,k;int head1,tail1,head2,tail2;int a[MAXN];struct node{    int val,index;}que1[MAXN],que2[MAXN];int main(){    //freopen("text.txt","r",stdin);    while(~scanf("%d%d%d",&n,&m,&k))    {        for(int i=1;i<=n;i++)            scanf("%d",&a[i]);        int ans=0,last1=0,last2=0;        head1=tail1=head2=tail2=0;        for(int i=1;i<=n;i++)        {            while(head1<tail1 && que1[tail1-1].val>a[i]) tail1--;            que1[tail1].val=a[i]; que1[tail1++].index=i;            while(head2<tail2 && que2[tail2-1].val<a[i]) tail2--;            que2[tail2].val=a[i]; que2[tail2++].index=i;            while(que2[head2].val-que1[head1].val>k)            {                if(que2[head2].index<que1[head1].index)                    last2=que2[head2++].index;                else                    last1=que1[head1++].index;            }            if(que2[head2].val-que1[head1].val>=m)                ans=max(ans,i-max(last1,last2));        }        printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击