LIS算法,一个小的知识点,最长上升子序列的改良版。

LIS模板

有N个整数,输出这N个整数的最长上升序列、最长下降序列、最长不上升序列和最长不下降序列。 
根据上述分析,我们应该十分容易就能够写出最后的程序,四个序列的代码基本相似 
 

转载此处:https://blog.csdn.net/Ronaldo7_ZYB/article/details/81111678(可看大佬更详细直接的lis算法)

代码如下:

#include<bits/stdc++.h>
using namespace std;
int n;
int a[800000];
int f[800000];
void Lis1()
{

    memset(f,0,sizeof(f));
    int len=0,pos;f[0]=-pow(10,9);
    for (int i=1;i<=n;i++)
    {
        if (a[i]>f[len]) f[++len]=a[i];
        else
        {
            int L=1,R=len,Mid;
            while (L+1<R)
            {
                Mid=(L+R)>>1;
                if (a[i]>f[Mid]) L=Mid;
                else R=Mid;
            }
            if (a[i]>f[L]) pos=R;
            else pos=L;
            f[pos]=min(f[pos],a[i]); 
        }
    }
    cout<<len<<endl;
}
void Lis2()
{
    memset(f,0,sizeof(f));
    int len=0,pos;f[0]=pow(10,9);
    for (int i=1;i<=n;i++)
    {
        if (a[i]<f[len]) f[++len]=a[i];
        else
        {
            int L=1,R=len,Mid;
            while (L+1<R)
            {
                Mid=(L+R)>>1;
                if (a[i]<f[Mid]) L=Mid;
                else R=Mid;
            }
            if (a[i]<f[L]) pos=R;
            else pos=L;
            f[pos]=max(f[pos],a[i]);
        }   
    }
    cout<<len<<endl;
}
void Lis3()
{
    memset(f,0,sizeof(f));
    int len=0,pos;f[0]=pow(10,9);
    for (int i=1;i<=n;i++)
    {
        if (a[i]<=f[len]) f[++len]=a[i];
        else
        {
            int L=1,R=len,Mid;
            while (L+1<R)
            {
                Mid=(L+R)>>1;
                if (a[i]<=f[Mid]) L=Mid;
                else R=Mid;
            }
            if (a[i]<=f[L]) pos=R;
            else pos=L;
            f[pos]=max(f[pos],a[i]); 
        }
    }
    cout<<len<<endl;
}
void Lis4()
{
    memset(f,0,sizeof(f));
    int len=0,pos;f[0]=-pow(10,9);
    for (int i=1;i<=n;i++)
    {
        if (a[i]>=f[len]) f[++len]=a[i];
        else
        {
            int L=1,R=len,Mid;
            while (L+1<R)
            {
                Mid=(L+R)>>1;
                if (a[i]>=f[Mid]) L=Mid;
                else R=Mid;
            }
            if (a[i]>=f[L]) pos=R;
            else pos=L;
            f[pos]=min(f[pos],a[i]); 
        }   
    }
    cout<<len<<endl;
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    for (int i=1;i<=n;i++)

        cin>>a[i];
    Lis1();
    Lis2();
    Lis3();
    Lis4();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq1013459920/article/details/81139494