1.题目描述:
2.题意概述:
给定一个数列,你可以不改变或者对其中一个数+1,问你最长上升子序列
3.解题思路:
将原数组分割成递增的子串,记录下每个子串的开始和结束位置,以及长度。
接下来要分几种情况讨论:
1.相邻的两个子串改变一个数字之后,可以合并形成新的递增子串。
2.相邻的3个子串,中间子串长度为1,改变中间的数字后可以形成新的递增子串。
3.相邻的子串不能合并形成新的递增子串,但是可以在原串的基础上,得到一个长度增加1的新的递增子串(在子串开头位置前有数字,或是结束位置后有数字)。
4.AC代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define maxn 100100
using namespace std;
int a[maxn];
struct node
{
int l, r, len;
}p[maxn];
int main()
{
int n;
while (scanf("%d", &n) != EOF)
{
memset(p, 0, sizeof(p));
memset(a, 0, sizeof(a));
int cnt = 0, ans;
for (int i = 0; i < n; i++)
{
scanf("%d", &a[i]);
if (i == 0)
{
p[cnt].len++;
p[cnt].l = p[cnt].r = i;
continue;
}
if (a[i] <= a[i - 1])
cnt++;
if (p[cnt].len == 0)
p[cnt].l = i;
p[cnt].r = i;
p[cnt].len++;
}
if (p[0].len < n)
ans = p[0].len + 1;
else
ans = p[0].len;
for (int i = 1; i <= cnt; i++)
{
ans = max(ans, p[i].len + 1);
if (a[p[i].l] > a[p[i - 1].r - 1] + 1 || a[p[i].l + 1] > a[p[i - 1].r] + 1)
ans = max(ans, p[i].len + p[i - 1].len);
if (i >= 2 && p[i - 1].len == 1 && a[p[i].l] > a[p[i - 2].r + 1])
ans = max(ans, p[i].len + p[i - 1].len + p[i - 2].len);
}
printf("%d\n", ans);
}
return 0;
}