int maxup(int *ta,int tlen)//原数组从1到n,长度tlen
{
int temp[maxn];//存长度i结尾的最小值
temp[0]=-INF;
temp[1]=ta[1];
int maxLen=1;
for(int i=2;i<=tlen;i++)
{
//if(ta[i]>=temp[maxLen])//非严格
if(ta[i]>temp[maxLen])//严格
temp[++maxLen]=ta[i];
else
{
//int pos=upper_bound(temp,temp+maxLen,ta[i])-temp;//非严格
int pos=lower_bound(temp,temp+maxLen,ta[i])-temp;//严格
temp[pos]=ta[i];
}
}
return maxLen;
}
再补充一种用状压来写最长上升子序列的写法
与上面nlogn的写法类似,也是可以理解为要存一个数组ans来存当前值可以插入的位置,所以用这种方法的时候,要保证a数组中的值都很小,不然存不下
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[110];
ll lcs(ll st,ll x)
{
for(ll i=x;i<64;i++){ //最大为2^63
if(st&(1<<i)){ //有更优解,就替换
st^=(1<<i); //消除
st|=(1<<x); //记录
return st;
}
}
st=st|(1<<x);
return st; //否则长度++
}
ll get(ll st)
{
ll cnt=0;
while(st){
if(st&1)
cnt++;
st>>=1;
}
return cnt;
}
ll maxup(ll *ta,ll alen)//数组从0到n-1
{
ll st=0; //状态
for(ll i=0;i<alen;i++){
st=lcs(st,ta[i]);
}
return get(st);
}
int main()
{
ll i,n;
scanf("%lld",&n);
for(i=0;i<n;i++){
scanf("%lld",&a[i]);
}
printf("%lld\n",maxup(a,n));
return 0;
}