1.动态规划(平方级复杂度)
import java.util.*;
import java.math.*;
import java.io.*;
import java.text.*;
public class Main
{
static int a[]=new int[5000];
static int status[]=new int[50000];
public static void main(String args[])throws IOException
{
BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
String tmp=bf.readLine();
int n=Integer.parseInt(tmp);
tmp=bf.readLine();
String tmps[]=tmp.trim().split(" ");
for(int i=1;i<=n;i++)
a[i]=Integer.parseInt(tmps[i-1]);
for(int i=1;i<=n;i++)
status[i]=1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<i;j++)
{
if(a[i]>a[j])
status[i]=Math.max(status[i],status[j]+1);//枚举状态
}
}
int ans=0;
for(int i=1;i<=n;i++)
ans=Math.max(ans,status[i]);
System.out.println(ans);
bf.close();
}
}
2.利用贪心与二分找到数值最小的上升子序列(一次方*对数级)
import java.util.*;
import java.math.*;
import java.io.*;
import java.text.*;
public class Main
{
static final int INF=0x3f3f3f3f;
static int lower[]=new int[500000];
static int datas[]=new int[500000];
public static int Binary_Search(int left,int right,int value)//二分查找第一个大于value的位置
{
int lowerr=left,upper=right;
while(lowerr<=upper)
{
int mid=(lowerr+upper)>>1;
if(lower[mid]<=value)
lowerr=mid+1;
else
upper=mid-1;
}
return lowerr;
}
public static void main(String args[])throws IOException
{
BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
String tmp=bf.readLine();
int n=Integer.parseInt(tmp);
tmp=bf.readLine();
String tmps[]=tmp.trim().split(" ");
for(int i=1;i<=n;i++)
datas[i]=Integer.parseInt(tmps[i-1]);
for(int i=1;i<=n;i++)
lower[i]=INF;
lower[1]=datas[1];//初始化LIS的第一个元素
int ans=1;
for(int i=2;i<=n;i++)
{
if(datas[i]>lower[ans])
lower[++ans]=datas[i];//如果小于末尾元素,直接加上去。
else
{
int location=Binary_Search(1,ans,datas[i]);//否则就把那个大于它的元素修改了
lower[location]=datas[i];
}
// for(int u=1;u<=ans;u++)
// System.out.print(lower[u]+" ");
// System.out.println("");
}
System.out.println(ans);
bf.close();
}
}