题意:给你一个长度为n的序列,你的任务是删除一个连续的子序列,使得剩下的序列当中有一个长度最大的连续递增子序列。
思路:我们想枚举每一个数字,看他能最多向左和向右可以延伸到哪里,然后我们就可以开始枚举i,j了,但是直接枚举的话时间复杂度是不够,所以我们可以仿造最大上升子序列的方法,进行优化将时间复杂度缩减到O(nlogn),就可以了。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#define MAXN 200010
#define MAXE 210
#define INF 10000000
#define MOD 1000000007
#define LL long long
#define pi acos(-1.0)
using namespace std;
int arr[MAXN];
int Left[MAXN];
int Right[MAXN];
int Min[MAXN];
int main() {
std::ios::sync_with_stdio(false);
int T;
cin >> T;
for (int kase = 1; kase <= T; ++kase) {
memset(Left, 0, sizeof(Left));
memset(Right, 0, sizeof(Right));
int n;
cin >> n;
for (int i = 1; i <= n; ++i)
cin >> arr[i];
Left[1] = 1;
for (int i = 2; i <= n; ++i) {
if (arr[i] > arr[i - 1])
Left[i] = Left[i - 1] + 1;
else
Left[i] = 1;
}
Right[n] = 1;
for (int i = n - 1; i >= 1; --i) {
if (arr[i] < arr[i + 1])
Right[i] = Right[i + 1] + 1;
else
Right[i] = 1;
}
int ans = 0;
memset(Min, 0x3f, sizeof(Min));
for (int i = 1; i <= n; i++) {
int len = lower_bound(Min + 1, Min + 1 + n, arr[i]) - Min - 1;
ans = max(ans, Right[i] + len);
Min[Left[i]] = min(Min[Left[i]], arr[i]);
}
cout << ans << endl;
}
return 0;
}
/*
2
9
5 3 4 9 2 8 6 7 1
7
1 2 3 10 4 5 6
*/