Codeforces Round #FF (Div. 2)C - DZY Loves Sequences

本博客介绍了一个算法挑战,即在一个整数序列中找到最长的子序列,允许调整一个元素使其变为任意整数,以确保整个子序列严格递增。通过详细解释解决方案,包括预处理序列来存储最长递增子序列信息,并在遍历原始序列时应用贪心策略,实现高效求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C. DZY Loves Sequences
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

DZY has a sequence a, consisting of n integers.

We'll call a sequence ai, ai + 1, ..., aj (1 ≤ i ≤ j ≤ n) a subsegment of the sequence a. The value (j - i + 1) denotes the length of the subsegment.

Your task is to find the longest subsegment of a, such that it is possible to change at most one number (change one number to any integer you want) from the subsegment to make the subsegment strictly increasing.

You only need to output the length of the subsegment you find.

Input

The first line contains integer n (1 ≤ n ≤ 105). The next line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 109).

Output

In a single line print the answer to the problem — the maximum length of the required subsegment.

Sample test(s)
input
6
7 2 3 1 5 6
output
5
Note

You can choose subsegment a2, a3, a4, a5, a6 and change its 3rd element (that is a4) to 4.

题意:

给一个有n个数字的序列,问最多只可以改变一个数字的前提下,最长上升子序列的长度是多少?(严格上升,也就是不能相等)。

解法:

我是先把每一段的最长子序列先用数组b表示。数组b表示最长的上升子序列末尾数字的位置。然后从pos=1开始在a序列往后找,遇到当前数字小于前一个数字开始进行判断。选择改变当前数字,是在前一个数字上+1,还是-1,这个取决于前面序列+后面序列大还是后面序列+前面序列大。好吧,看起来好像是一样,其实不然。举个例子。

序列:1 3 6 4 2 3 4 6。当我们取到第五个数字2的时候,我们是把2变成5还是把前面的4变成1,这个当然改变4为1时子序列最大为5。如果序列是:1 3 2 4 2 6 7 8。同样我们取到第五个数字2的时候,改变2为5时子序列最大为6。这就是两种情况的不同需要考虑。当然最后还有一个特殊情况。本来就是严格的递增序列,所以就直接呵呵了。嗯,直接上代码。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <queue>
#include <map>
#include <stack>
#include <list>
#include <vector>
using namespace std;
#define Max(a,b) a>b?a:b
int n,i;
int a[100010];
int b[100010];
int main()
{
	scanf("%d",&n);
	a[0]=0;
	b[n+1]=0x3fffffff;
	for (i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for (i=n;i>0;i--)
		if (a[i]<a[i+1]) b[i]=b[i+1];
		else b[i]=i;
	int pos=1;
	int max=0;
	for (i=1;i<=n;i++)
	{
		if (a[i]<=a[i-1]) 
		{
			if (a[i]-1<=a[i-2])
				max=Max(max,b[i]-i+2);
			else max=Max(max,b[i]-pos+1);
			if (a[i-1]+1>=a[i+1]) 
				max=Max(max,i-pos+1);
			else max=Max(max,b[i]-pos+1);
			pos=i;
		}
	}
	if (pos==1) max=n;
	printf("%d\n",max);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值