欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

LIS & LCS

程序员文章站 2022-06-06 14:34:27
...

题意:
有两个序列A和B。想要知道序列A的LIS和序列AB的LCS的长度。注意,LIS为严格递增的,即a1<a2<…<ak(ai<=1,000,000,000)。
输入:
第一行两个数n,m(1<=n<=5,000,1<=m<=5,000)
第二行n个数,表示序列A
第三行m个数,表示序列B
输出:
输出一行数据ans1和ans2,分别代表序列A的LIS和序列AB的LCS的长度。
解题思路:
最长上升子序列:
LIS & LCS
这里用一个一维数组f来表示各个最长上升序列的长度。
最长公共子序列:
LIS & LCS
这里用一个二维数组g来表示各个最长公共子序列的长度。
注意事项:
每一个序列的长度最大为5000,因此无论是最长公共子序列还是最长上升子序列的长度都不会超过5000,而数组f和g的值都只代表序列的长度,因此使用 int 类型的数据足矣。
参考代码:

#include <iostream>
using namespace std;
int n,m;
int a[5005];
int b[5005];
int f[5005];
int g[5005][5005];
int ans1=0,ans2=0;
int getmax(int a,int b){
    if(a>b)return a;
    return b;
}
int solve(int i){
    int mymax=0;
    for (int j=1; j<i; j++) {
        if(a[j]<a[i]){
            if(f[j]>mymax)mymax=f[j];
        }
    }
    return mymax+1;
}
int main(int argc, const char * argv[]) {
    cin>>n>>m;
    for (int i=1; i<=n; i++) {
        cin>>a[i];
    }
    for (int i=1; i<=m; i++) {
        cin>>b[i];
    }
    f[1]=1;
    int mymax=1;
    for (int i=2; i<=n; i++) {
        f[i]=solve(i);
        if(f[i]>mymax)mymax=f[i];
    }
    cout<<mymax<<" ";
    g[1][0]=g[0][1]=g[0][0]=0;
    for (int i=1; i<=n; i++)
        for(int j=1;j<=m;j++)
    {
        if(a[i]==b[j])g[i][j]=g[i-1][j-1]+1;
        else g[i][j]=getmax(g[i-1][j], g[i][j-1]);
    }
    cout<<g[n][m]<<endl;
    return 0;
}