Subsequence

Subsequence

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


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 0 1 1 1 1 1 5 0 3 1 2 3 4 5
 

Sample Output
  
5 4
 

Source
 
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
int a[100005];
int main()
{
	int n,m,k,i,now,ans;
	while(~scanf("%d%d%d",&n,&m,&k))
	{
		for(i=1;i<=n;i++)
		scanf("%d",&a[i]);
        deque<int>q;
        q.clear();
        deque<int>Q;
        Q.clear();
        now=1,ans=0;
        for(i=1;i<=n;i++)
        {
        	while(!q.empty()&&a[i]<a[q.back()])//单调递增序列
        	q.pop_back();
        	q.push_back(i);
        	while(!Q.empty()&&a[i]>a[Q.back()])//单调递减序列
        	Q.pop_back();
        	Q.push_back(i);
        	while(!q.empty()&&!Q.empty()&&a[Q.front()]-a[q.front()]>k)
        	{
        		if(q.front()<Q.front())
        		{
                    now=q.front()+1;
                    q.pop_front();
        	    }
        		else
        		{
                    now=Q.front()+1;
                    Q.pop_front();
        	    }
        	}
        	if(a[Q.front()]-a[q.front()]>=m)
        	{
        		if(ans<i-now+1)
        		ans=i-now+1;
        	//	cout<<"ans= "<<ans<<endl;
        	}
        	/*
                这一题用两个队列维护区间
                一个单调递增序列一个单调递减序列
                两个头的值相减就是区间的范围
                所以每次插入一个值的时候必须让这个值遵循规则
                now只能在数列元素加一的时候才能动!
        	*/
        }
        printf("%d\n",ans);
	}
	return 0;
}
/*
8 2 6
1 3 8 5 2 7 5 2
*/


### is_subsequence 函数或算法的详细信息 `is_subsequence` 是一种常见的算法或函数,用于判断一个字符串是否为另一个字符串的子序列。具体来说,如果可以通过删除某些字符而不改变其余字符顺序的方式从目标字符串中获得给定的子串,则该子串被认为是目标字符串的一个子序列。 #### 算法描述 此问题通常可以采用双指针技术来解决。两个指针分别指向输入字符串 `s` 和目标字符串 `t` 的起始位置。遍历过程中,当发现匹配时移动到下一个待比较字符的位置;如果没有找到完全匹配的情况,则返回 False 表明 `s` 不是 `t` 的子序列[^1]。 下面是一个 Python 实现的例子: ```python def is_subsequence(s: str, t: str) -> bool: s_idx, t_idx = 0, 0 while s_idx < len(s) and t_idx < len(t): if s[s_idx] == t[t_idx]: s_idx += 1 t_idx += 1 return s_idx == len(s) ``` 在这个例子中,我们初始化了两个索引变量 `s_idx` 和 `t_idx` 来追踪各自字符串中的当前位置。每当遇到相等元素的时候就只推进较小的那个字符串即`s`上的指针,而无论何时都会尝试去读取`t`里的下一位直到完成整个扫描或者提前结束循环因为已经找到了全部所需字母[^2]。 #### 时间复杂度分析 由于每次迭代最多只会增加其中一个索引(`s_idx`, 或者 `t_idx`) ,因此总体时间复杂度为 O(n + m),其中 n 和 m 分别代表字符串 `s` 和 `t` 的长度[^3]。 #### 动态规划视角下的解释 虽然上述解法利用的是贪心策略配合简单的线性扫描即可高效解决问题,但从理论上讲也可以借助动态规划的思想重新构建解决方案——尽管这可能带来不必要的额外开销。例如定义状态转移方程如下所示: 设 f[i][j] 表示考虑前i个字符组成的模式串pattern[:i] 是否能成为文本text[:j] 中某部分连续片段构成的有效子序列关系。那么就有递推公式: f[i][j]=true 如果 pattern[i]==text[j] 并且 f[i−1][j−1]==true; 否则的话只要存在某个 k<j 让得 f[i][k]==true 即可使得当前项成立[^4]. 然而实际操作层面考虑到空间效率等因素一般不会这样去做除非特别需求场景下才如此处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值