#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + 5;
int num[maxn]; //原数列
int sign1[maxn]; //从开始标记
int sign2[maxn]; //从末尾标记
int n, ans;
int main()
{
while(~scanf("%d", & n))
{
ans = 0;
memset(num, 0, sizeof(num)); //初始化(主要是 num[0] = 0 num[n + 1] = 0)
memset(sign1, 0, sizeof(sign1));
memset(sign2,0, sizeof(sign2));
for(int i = 1; i <= n; i ++)
scanf("%d", & num[i]); //输入n个数
sign1[1] = 1;
for(int i = 2; i <= n; i ++) //sign1开始依次计数
{
if(num[i - 1] < num[i])
sign1[i] = sign1[i - 1] + 1;
else
sign1[i] = 1;
}
sign2[n] = 1;
for(int i = n - 1; i >= 1; i --) //sign2开始依次计数
{
if(num[i] < num[i + 1])
sign2[i] = sign2[i + 1] + 1;
else
sign2[i] = 1;
}
for(int i = 1; i <= n; i ++) //有两种可能
{
if(num[i + 1] - num[i - 1] >= 2) //1:两个连续的子序列可以连接
ans = max(ans, sign1[i - 1] + sign2[i + 1] + 1);
else //2: 两个子序列不能连接 取前后最大子列
ans = max(ans, max(sign1[i - 1] + 1, sign2[i + 1] + 1));
}
printf("%d\n", ans);
}
return 0;
}
题意:
输入n,之后输入n个数。可以改变其中一个数。问改变后最大子序列长度多少。
题解:
也难说。来几个例子吧。其实可以从i = 0开始,不过看过去有点bug(i + 1 或者 i - 1 在i = n - 1 或者 i = 0会超范围),但是还是可以过。不过还是改成如上的代码。
num = 0 7 2 3 1 5 6 0 (实际前后各有一个0)
sign1 = 0 1 1 2 1 2 3 0
sign2 = 0 1 2 1 3 2 1 0
谈下前后设0的问题: i = 1 的时候,num[i - 1] = 0, num[i + 1] = 2, 符合条件则可以连接 0 + 1 + 1= 2。(把7变成1)
i = n 的时候,num[i - 1] = 5, num[i + 1] = 0, 不符合 >= 2,则取ans = max(ans, max(3, 0) = 3)。(已到末尾,只有取前面)
程序走到了1(i = 4)后, 5 - 3 = 2符合,则连接——sign1[3] = 2, sign2[4] = 2, 则长度为 2 + 2 + 1 = 5。