牛牛现在有一个n个数组成的数列,牛牛现在想取一个连续的子序列,并且这个子序列还必须得满足:最多只改变一个数,就可以使得这个连续的子序列是一个严格上升的子序列,牛牛想知道这个连续子序列最长的长度是多少。
最长上升子序列的变形,要从前往后求一遍,从后往前求一遍,枚举中间点。。。
主要思想是从前往后扫一遍和从后往前扫一遍。。。
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<iostream>
#define LL long long
using namespace std;
int num[100005];
struct Node
{
int le, ri, sn;
};
Node data[100005];
bool cmp(Node na, Node nb)
{
return na.le < nb.le;
}
int main()
{
int n;
while(scanf("%d", &n) != EOF)
{
for(int i = 0 ; i < n ; i++)
scanf("%d", &num[i]);
int ll = 0;
int cnt = 0;
int ans = 1;
for(int i = 1 ; i < n ; i++)
{
if(i == n - 1 || num[i] <= num[i - 1])
{
data[cnt].le = ll;
data[cnt].ri = i == n - 1 ? i : i - 1;
data[cnt].sn = data[cnt].ri - data[cnt].le + 1;
ans = max(ans, data[cnt].sn);
cnt++;
ll = i;
}
}
sort(data, data + cnt, cmp);
for(int i = 0 ; i < cnt - 1 ; i++)
{
int a = data[i].ri;
int b = data[i + 1].le;
if(data[i + 1].sn == 1)
{
ans = max(ans, data[i].sn + 1);
}
else if(data[i].sn == 1)
{
ans = max(ans, data[i + 1].sn + 1);
}
else
{
if(num[a] + 1 < num[b + 1])
{
ans = max(ans, data[i].sn + data[i + 1].sn);
}
if(num[a - 1] + 1 < num[b])
{
ans = max(ans, data[i].sn + data[i + 1].sn);
}
}
}
printf("%d\n", ans);
}
}