原序列倒过来,以当前位置为终点的,做一次最长不降序列 ,取负数,重复这个过程 可以用STL里的二分。。
ans为俩个长度之和减去最小重复数。 //这里需要特别注意的是 重复数要减去最小值,我之前的代码虽然能够AC,但是没考虑到这个问题。所以是hdu数据弱了。。。
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
#include <iostream>
using namespace std;
const int MAXN = 100010;
int val[MAXN];
int dp1,dp2;
int same;
vector<int>v1;
vector<int>v2;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
v1.clear();
v2.clear();
int n;
int ans=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&val[i]);
for(int i=1;i<=n;i++)
{
int a=lower_bound(v1.begin(),v1.end(),val[n-i])-v1.begin();
int b=upper_bound(v1.begin(),v1.end(),val[n-i])-v1.begin();
if(b==v1.size())
{
v1.push_back(val[n-i]);
dp1=v1.size();
}
else
{
v1[b]=val[n-i];
dp1=b+1;
}
same=b-a+1;
a=lower_bound(v2.begin(),v2.end(),-val[n-i])-v2.begin();
b=upper_bound(v2.begin(),v2.end(),-val[n-i])-v2.begin();
if(b==v2.size())
{
v2.push_back(-val[n-i]);
dp2=v2.size();
}
else
{
v2[b]=-val[n-i];
dp2=b+1;
}
same=min(same,b-a+1);
ans=max(dp1+dp2-same,ans);
}
printf("%d\n",ans);
}
return 0;
}
/*
10
2 2 2 2 1 2 2 2 3 3
*/