CF #605 div.3 D Remove One Element

You are given an array a consisting of n integers.

You can remove at most one element from this array. Thus, the final length of the array is n−1 or n.

Your task is to calculate the maximum possible length of the strictly increasing contiguous subarray of the remaining array.

Recall that the contiguous subarray a with indices from l to r is a[l…r]=al,al+1,…,ar. The subarray a[l…r] is called strictly increasing if al<al+1<⋯<ar.

Input
The first line of the input contains one integer n (2≤n≤2⋅105) — the number of elements in a.

The second line of the input contains n integers a1,a2,…,an (1≤ai≤109), where ai is the i-th element of a.

Output
Print one integer — the maximum possible length of the strictly increasing contiguous subarray of the array a after removing at most one element.

Examples
input
5
1 2 5 3 4
output
4
input
2
1 2
output
2
input
7
6 5 4 3 2 4 3
output
2
Note
In the first example, you can delete a3=5. Then the resulting array will be equal to [1,2,3,4] and the length of its largest increasing subarray will be equal to 4.

题意是在一个长度为n的序列中可以选择是否删去其中的一个元素,求最终序列里的最长严格子序列递增长度。
最开始看到这道题以为是一道dp(实际上cf上给的tag也确实是dp),无奈自己dp太弱,只能想想其他方法。
任何一个序列都可以分为一个或者多个严格递增的子序列(只有单个元素的子序列也是严格递增),首先把给出的元素处理成几个严格递增的子序列,再考虑删去一个元素的情况。
删去一个元素可以看做两个连续的严格递增子序列中删去前一个序列的最后一个元素或者删去后一个序列中的第一个元素,再判断两个剩下的序列能否重新拼成一个新的严格递增序列。

例如第一个样例
1 2 5 3 4 这个序列可以分成1 2 5和3 4这两个序列,这时符合条件的最长长度为3(序列1 2 5的长度),再删去1 2 5中的5,发现可以与后一个子序列3 4构成新的严格递增序列,且新序列的长度长于之前符合条件的最长长度,因此答案为4。

因此我们只需要知道每个严格递增子序列的起始位置和终止位置就能完成,复杂度为O(n)。
还要加一个特判就是如果其中一个子序列长度为1,就不需要再判断它删去一个元素之后能不能和其他子序列构成新的严格递增序列了。
代码如下

#include<bits/stdc++.h>
using namespace std;
int n,a[220000];
int l[220000],r[220000],num=1;
int main(void){
    
    
	cin >> n;
	for(int i=1;i<=n;i++)
		cin >> a[i];
	l[num]=1;r[num]=1;
	for(int i=2;i<=n;i++){
    
    
		if(a[i]>a[i-1])
			r[num]++;
		else{
    
    
			num++;
			l[num]=i;
			r[num]=i;
		}
	}
	int maxlen=r[1]-l[1]+1;
	for(int i=2;i<=num;i++){
    
    
		maxlen=max(maxlen,r[i]-l[i]+1);
		if(l[i]!=r[i])
			if(a[l[i]+1]>a[r[i-1]])
				maxlen=max(maxlen,r[i]-l[i-1]);
		if(l[i-1]!=r[i-1])
			if(a[l[i]]>a[r[i-1]-1])
				maxlen=max(maxlen,r[i]-l[i-1]);
	}
	cout << maxlen << '\n';
}

猜你喜欢

转载自blog.csdn.net/qq_45682135/article/details/103528238
今日推荐