最长子序列指的是在一串数字中,求得一个最大的区间,使得这个区间的所有数都是有规律的
一般分为两种,连续与不连续
直接从前往后遍历,线性遍历,时间复杂度为O(n)
#include
#define M 100005
using namespace std;
int a[M]={389, 207 ,155 ,300 ,299,170,158, 65},ans=0;
int main()
{
int sum=1;
for(int i=1;i<8;i++)
{
if(a[i]>a[i-1])
sum++;
else
ans=max(ans,sum), sum=1;
}
cout<
我们以求递增序(不可以相等)列为例
这个时候,就需要另开一个数组ris,用来存放所求的递减序列,分两种情况:
至于lower_bound与upper_bound : https://blog.csdn.net/qq_41431457/article/details/88919340
#include
#define M 100005
using namespace std;
int a[M]={0,389,207,155,300,299,170,158,65};
int ris[M];
int main()
{
int len=1;
ris[1]=a[1];//初始化
for(int i=2;i<8;i++)
{
if(a[i]<=ris[len])//找到ris中第一个 >=a[i]的
*lower_bound(ris+1,ris+len+1,a[i])=a[i];
else
ris[++len]=a[i];
}
cout<
求递减序列长度:
#include
#define M 100005
using namespace std;
int a[M]={0,389,207,155,300,299,170,158,65};
int dro[M];
bool cmp( int a, int b)
//自定义比较函数,使得lower_bound求的是比第一个目标值小的
{
return a>b;
}
int main()
{
int len=1;
dro[1]=a[1];//初始化
for(int i=2;i<=8;i++)
{
if(a[i]>=dro[len])//找到dro中第一个a[i]小的
*lower_bound(dro+1,dro+len+1,a[i],cmp)=a[i];//替换
else
dro[++len]=a[i];
}
cout<
Dynamic programming:
opt[i] 表示以i结尾的最长序列, 则 面对第i+1个数, 如果这个数比第i个数大, 则再1-i个数中找到一个比a[i] 小的数 ,取最大的opt
for(int i=1; i<=n; i++)
{
opt[i]=1;
for(int j=1; j