最长上升子序列
O(n*logn)
//#pragma commmpnt(linkmpr, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
typedef long long LL;
const int M = 100010;
const int INF =0x3f3f3f3f;
const int MAXN=10010;
int a[MAXN],b[MAXN];
//用二分查找的方法找到一个位置,使得num>b[i-1] 并且num<b[i],并用num代替b[i]
int Search(int num,int low,int high)
{
int mid;
while(low<=high)
{
mid=(low+high)/2;
if(num>=b[mid]) low=mid+1;
else high=mid-1;
}
return low;
}
int DP(int n)
{
int i,len,pos;
b[1]=a[1];
len=1;
for(i=2; i<=n; i++)
{
if(a[i]>b[len])//如果a[i]比b[]数组中最大还大直接插入到后面即可
{
len=len+1;
b[len]=a[i];
}
else //用二分的方法在b[]数组中找出第一个比a[i]大的位置并且让a[i]替代这个位置
{
pos=Search(a[i],1,len);
b[pos]=a[i];
}
}
return len;
}
int main()
{
int n;
scanf("%d",&n);
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(int i=1;i<=n;++i)
{
cin>>a[i];
}
cout<<DP(n)<<endl;
return 0;
}
O(n^2)
//#pragma commmpnt(linkmpr, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
typedef long long LL;
const int M = 100010;
const int INF =0x3f3f3f3f;
const int MAXN=10010;
int a[MAXN],b[MAXN];
int dp[MAXN];
int main()
{
int n;
scanf("%d",&n);
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(dp,0,sizeof(dp));
for(int i=1; i<=n; ++i)
{
cin>>a[i];
}
int maxlen=0;
//dp[1]=0;
for(int i=1; i<=n; ++i)
{
dp[i]=1;
for(int j=1; j<=i; ++j)
{
if(a[j]<a[i] && dp[j]+1 >dp[i])
{
dp[i]=dp[j]+1;
}
if(dp[i]>maxlen)
{
maxlen=dp[i];
}
}
}
cout<<maxlen<<endl;
return 0;
}