集合:所以**a[i]
**为结尾的严格单调递增的子序列
属性:max
注:子序列的结尾必定是以某个数a[i]
作为结尾,我们求出所有数作为结尾的子序列**,然后取一个max即可。
所有以a[i]
为结尾的子序列,说明a[i]
均相同,我们根据最后一个不同的点划分。
根据最后一个不同的点,可以将最后一个不同的点以**a[1]
、a[2]
、a[3]
、…a[i-1]
这几类进行划分,由于这几类划分标准的共同点均是以a[i]
结尾,所以最后再加上a[i]这个点即可,即长度加1**。
f [ i ] = M a t h . m a x ( f [ i ] , f [ j ] + 1 ) f[i]=Math.max(f[i],f[j]+1) f[i]=Math.max(f[i],f[j]+1)
特殊情况:只有a[i]
自己一个数的时候,此时长度为1
。这里需要在循环时进行特判,如果前面找不到比a[i]
小的数,即a[j]>=a[i]
时,则不需要更新长度。
a[j]>a[i]:
我们是以a[i]
作为结尾的子序列,子序列严格递增,a[i]
是最大的那个数。前面出现比a[i]
大的数就不满足这一条件,不需更新长度。
a[j]=a[i]:
当出现a[j]=a[i]
时说明这两个数相同,我们只需要保留**a[i]
这个数即可。即长度为1
import java.util.*;
public class Main{
static int N=1010;
static int a[]=new int[N];
static int f[]=new int[N];
public static void main(String []args){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
for(int i=1;i<=n;i++)a[i]=sc.nextInt();
for(int i=1;i<=n;i++){
f[i]=1;//初始化每个i结尾的序列长度为1
for(int j=1;j<i;j++){
if(a[j]<a[i]){
//特判一下
//a[j]
//a[j]>=a[i]说明序列不合法
f[i]=Math.max(f[i],f[j]+1);
}
}
}
long res=f[1];
for(int i=1;i<=n;i++){
res=Math.max(res,f[i]);
}
System.out.println(res);
}
}