https://www.cnblogs.com/frankchenfu/p/7107019.html 借鉴
最长上升子序列就是在一个序列中找到非递减的子序列,子序列可以不是连续的
一种方法就是固定一个i在0到i中找j j取或不取将影响到i 更新i的值 复杂度是O(n^2)
#include<cstdio>
const int MAX=1001;
int a[MAX];
int lis(int x)
{
int num[MAX];
for(int i=0;i<x;i++)
{
num[i]=1;
for(int j=0;j<i;j++)
{
if(a[j]<a[i]&&num[j]+1>num[i])
num[i]=num[j]+1;
}
}
int maxx=0;
for(int i=0;i<x;i++)
if(maxx<num[i])
maxx=num[i];
return maxx;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
return !printf("%d
",lis(n));
}
今天考到的第二个方法是用栈优化的 复杂度是O(nlgn)
用二分的思想....【其实我也不是特别理解】 这个二分其实是用stl lower_bound实现的
dp[i]=长度为i+1的上升子序列中末尾元素的最小值(不存在的话就是INF)
http://blog.csdn.net/zhangyx_xyz/article/details/50949957【参考】
几乎都没有用过的我感到非常惭愧 还去百度了一下是什么
【函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置】
#include<cstdio>
#include<algorithm>
const int MAXN=200001;
int a[MAXN];
int d[MAXN];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
d[1]=a[1];
int len=1;
for(int i=2;i<=n;i++)
{
if(a[i]>d[len])
d[++len]=a[i];
else
{
int j=std::lower_bound(d+1,d+len+1,a[i])-d;
d[j]=a[i];
}
}
printf("%d
",len);
return 0;
}