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的长度。
解题思路:
最长上升子序列:
这里用一个一维数组f来表示各个最长上升序列的长度。
最长公共子序列:
这里用一个二维数组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;
}