时间复杂度
O(kmlogm),k是组数,m是数组长度
算法思想
单调栈问题
分别计算从左向右和从右向左的最长上升子序列,取最大值即可
java 代码
//单调栈问题
//分别计算从左向右和从右向左的最长上升子序列,取最大值即可
import java.io.*;
import java.util.*;
class Main{
static int n = 0, N = 110;
static int[] nums = new int[N];
static int bs(int[] max, int len, int num){//找到从左到右第一个大于于num的数字
int l = 0, r = len;
while(l < r){
int mid = l + r >> 1;//+1防止mid不变造成死循环。
if(max[mid] < num)l = mid + 1;
else r = mid;
}
return l;
}
public static void main(String[] args)throws Exception{
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
while(n -- != 0){
int m = sc.nextInt();
for(int i = 1; i <= m; ++i)nums[i] = sc.nextInt();
int[] st = new int[N];//单调栈
int tt = -1;
int max = 0;
for(int i = 1; i <= m; ++i){
if(tt == -1)st[++tt] = nums[i];
if(tt > 0 && st[tt] > nums[i]){
int index = bs(st, tt, nums[i]);
st[index] = nums[i];
}
if(st[tt] < nums[i])st[++tt] = nums[i];
}
max = tt + 1;
tt = -1;
for(int i = m; i >= 1; --i){
if(tt == -1)st[++tt] = nums[i];
if(tt > 0 && st[tt] > nums[i]){
int index = bs(st, tt, nums[i]);
st[index] = nums[i];
}
if(st[tt] < nums[i])st[++tt] = nums[i];
}
max = Math.max(max, tt + 1);
System.out.println(max);
}
}
}