Subsequence
PS:因原文为英文,所以下文为翻译软件(有道词典)的翻译,翻译不准请见谅
问题描述
有一个整数序列。你的任务是找到满足以下条件的lcs: lcs的最大元素和最小元素的差不小于m,也不大于k。
输入
有多个测试用例。
对于每个测试用例,第一行有三个整数,n, m, k。n是序列的长度,在[1,100000]的范围内。m和k在[0,1000000]范围内。第二行有n个整数,都在[0,1000000]的范围内。
继续到文件的末尾。
输出
对于每个测试用例,在一行上打印子序列的长度。
样例输入
5 0 0
1 1 1 1 1
5 0 3
1 2 3 4 5
样例输出
5
4
解题思路
正着来一遍,反着来一遍,提交来一遍,AC来一遍
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,k,a[100010];
int hd1,hd2,tl1,tl2;
int last,ans;
int f1[100010],f2[100010];
int max(int a,int b)
{
if(a>b)
return a;
return b;
}
int main()
{
while(scanf("%d%d%d",&n,&m,&k)==3)
{
memset(f1,0,sizeof(f1));
memset(f2,0,sizeof(f2));
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
hd1=hd2=1;
tl1=tl2=0;
ans=0;
last=1;
for(int i=1;i<=n;i++)
{
while(tl1>=hd1&&a[f1[tl1]]<a[i]) tl1--;
f1[++tl1]=i;
while(tl2>=hd2&&a[f2[tl2]]>a[i]) tl2--;
f2[++tl2]=i;
while(a[f1[hd1]]-a[f2[hd2]]>k)
{
if(f1[hd1]<f2[hd2])
{
last=f1[hd1]+1;
hd1++;
}
else
{
last=f2[hd2]+1;
hd2++;
}
}
if(a[f1[hd1]]-a[f2[hd2]]>=m)
ans=max(ans,i-last+1);
}
cout<<ans<<endl;
}
}