最长上升(非递减)子序列(LIS)和最长公共子序列(LCS)

896. 最长上升子序列 II

给定一个长度为 \(N\) 的数列,求数值严格单调递增的子序列的长度最长是多少。

输入格式

第一行包含整数 \(N\)

第二行包含 \(N\) 个整数,表示完整序列。

输出格式

输出一个整数,表示最大长度。

数据范围

\(1≤N≤100000\)
\(−10^9≤数列中的数≤10^9\)

输入样例:

7
3 1 2 1 8 5 6

输出样例:

4

提示

\(f[i]\) 表示长度为 \(i\) 且序列结尾最小的值

  • 时间复杂度:\(O(nlogn)\)

代码

#include<bits/stdc++.h>
using namespace std;
int n,f[100005];
int main()
{
    scanf("%d",&n);
    int x,len=0;
    f[0]=-0x3f3f3f3f;
    for(int i=1;i<=n;i++)
    {
        f[i]=0x3f3f3f3f;
        scanf("%d",&x);
        if(x>f[len])f[++len]=x;
        else
        {
            int pos=lower_bound(f+1,f+1+len,x)-f;
            f[pos]=x;
        }
    }
    printf("%d",len);
    return 0;
}
  • 最长非递减子序列
int LNDS(vector<int> nums)
{
    //f[i]表示长度为i,最长非递减子序列结尾的最小值
    vector<int> f;
    f.push_back(nums[0]);
    int n=nums.size();
    for(int i=1;i<n;i++)
    {
        if(nums[i]>=f.back())f.push_back(nums[i]);
        else
        {
            int pos=upper_bound(f.begin(),f.end(),nums[i])-f.begin();
            f[pos]=nums[i];
        }
    }
    return f.size();
}

3510. 最长公共子序列

给出两个长度为 \(n\) 的整数序列,求它们的最长公共子序列(LCS)的长度,保证第一个序列中所有元素都不重复。

注意:

  • 第一个序列中的所有元素均不重复。
  • 第二个序列中可能有重复元素。
  • 一个序列中的某些元素可能不在另一个序列中出现。

输入格式

第一行包含一个整数 \(n\)

接下来两行,每行包含 \(n\) 个整数,表示一个整数序列。

输出格式

输出一个整数,表示最长公共子序列的长度。

数据范围

\(1≤n≤10^6\),
序列内元素取值范围 \([1,10^6]\)

输入样例1:

5
1 2 3 4 5
1 2 3 4 5

输出样例1:

5

输入样例2:

5
1 2 3 5 4
1 2 3 4 5

输出样例2:

4

提示

将第一个序列离散化,即将值与其下标对应起来,再将第二个序列中的值对应起来,没有在第一个序列出现过的值不用管,下标显然是上升的,即转化为求第二个对于序列的 \(LIS\)~

  • 时间复杂度:\(O(nlogn)\)

代码

#include<bits/stdc++.h>
using namespace std;
int n,x,f[1000005],id[1000005];
int main()
{
    scanf("%d",&n);
    memset(id,-1,sizeof id);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&x);
        id[x]=i;
        f[i]=0x3f3f3f3f;
    }
    f[0]=0;
    int len=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&x);
        if(id[x]==-1)continue;
        if(id[x]>f[len])f[++len]=id[x];
        else
        {
            int pos=lower_bound(f+1,f+1+len,id[x])-f;
            f[pos]=id[x];
        }
    }
    printf("%d",len);
    return 0;
}
posted @ 2021-11-18 15:57  zyy2001  阅读(167)  评论(0编辑  收藏  举报