//以后每一发炮弹都不能高于前一发的高度,所以说可以等于 此处我们要求的原序列的最长非递增序列(也就是递减和等于)
//将字符串逆序以下,就可以求(最长递增和等于序列)
关键是处理等于的情况。
package com.company.luogu;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
public class P1020 {
public static void main(String[] args) throws Exception{
BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
String[] str=reader.readLine().split(" ");
int[] arr=new int[str.length];
int[] arrb=new int[str.length];
for (int i = 0; i <str.length ; i++) {
arr[i]=Integer.parseInt(str[i]);
arrb[arr.length-1-i]=arr[i];
}
//以后每一发炮弹都不能高于前一发的高度,所以说可以等于 此处我们要求的原序列的最长非递增序列(也就是递减和等于)
//将字符串逆序以下,就可以求(最长递增和等于序列)
System.out.println(LEISArray(arrb));
System.out.println(LISArray(arr));//从dilworth定理中,我们可知,下降子序列的最小划分等于最长不下降子序列的长度 也就是最长递增和等于序列
reader.close();
}
public static int LEISArray(int[] arrs){
int[] list=new int[arrs.length+1];
Arrays.fill(list,Integer.MAX_VALUE);
list[0]=arrs[0];
int index=0;//保存数组当前的位置
for (int i = 1; i <arrs.length ; i++) {
if(arrs[i]>=list[index]){//比最后一位大或者相等,直接续接在最后就可以了
index++;
list[index]=arrs[i];
}else{
int zz=searchARR(list,arrs[i],index);//zz是这个数字在数组中的,比arrs[i]最后一个刚好大的位置
if(list[zz]==arrs[i]){//如果这个数字存在了,需要找到最后一个相等的位置
while(list[zz+1]==arrs[i]){
zz++;
}
if(zz==index){//如果相等的数据在最后,数组长度要增加一下
index++;
}
zz++;
list[zz]=arrs[i];
}else{//不相等的话,直接可以替换
list[zz]=arrs[i];
}
}
}
return index+1;
}
public static int LISArray(int[] arrs){
int[] list=new int[arrs.length+1];
Arrays.fill(list,Integer.MAX_VALUE);
list[0]=arrs[0];
int index=0;
for (int i = 1; i <arrs.length ; i++) {
if(arrs[i]>list[index]){//如果数据比当前最后的数据大,需要替换一下
index++;
list[index]=arrs[i];
}else{
int zz=searchARR(list,arrs[i],index);
if(list[zz]==Integer.MAX_VALUE){//如果相等的数据在最后,数组长度要增加一下
index++;
}
list[zz]=arrs[i];
}
}
//return index+1;
int c=0;
for (int i = 0; i <list.length ; i++) {
if(list[i]==Integer.MAX_VALUE){
break;
}
c++;
}
return c;
}
private static int searchARR(int[] list, int a,int endIndex) {//找到的是要替换的位置
int low=0;
//int high=list.length-1;
int high=endIndex;
while(low<=high){
int mid=(low+high)/2;
if(list[mid]==a){
return mid;
}else if(list[mid]>a){
high=mid-1;
}else{
low=mid+1;
}
}
return low;
}
}