样例输入:
5 5
1 3 2 5 4
2 4 3 1 5
样例输出:
3 2
对于第一部分LIS,设数组d存储着从1号元素到i号元素的序列的LIS最长长度。
转移方程为d[i]=max{j<i&&a[j]<a[i]}+1
d[1]=1;//初始化
for(int i=2;i<=n;i++)
{
int mx=0;
for(int j=1;j<i;j++)
{
if(a[i]>a[j])
{
if(d[j]>mx)//找到d[1]~d[j]中的最大值
{
mx=d[j];
}
}
}
d[i]=mx+1;
}
对于第二部分LCS, dp即为f图中的数组
dp[0][0]=dp[0][1]=dp[1][0]=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
if(a[i]==b[j])
{
dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
}
}
}
以下是完整代码:
#include<iostream>
#include<algorithm>
using namespace std;
int a[5100];
int b[5100],dp[5100][5100];
int d[5100];//d[i]表示序列从1~i中最长的LIS长度
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)//接收序列A
{
cin>>a[i];
}
for(int i=1;i<=m;i++)//接收序列B
{
cin>>b[i];
}
d[1]=1;//初始化
for(int i=2;i<=n;i++)
{
int mx=0;
for(int j=1;j<i;j++)
{
if(a[i]>a[j])
{
if(d[j]>mx)//找到d[1]~d[j]中的最大值
{
mx=d[j];
}
}
}
d[i]=mx+1;
}
dp[0][0]=dp[0][1]=dp[1][0]=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
if(a[i]==b[j])
{
dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
}
}
}
int ans1=d[1];
for(int i=1;i<=n;i++)
{
ans1=max(ans1,d[i]);
}
cout<<ans1<<" "<<dp[n][m];
}