正题
题目链接:http://www.joyoi.cn/problem/tyvj-1071
题目大意
求两个序列的最长公共上升子序列。
code
我们先回顾一下LIS和LCS
LIS:
fi=max{fj+1}(j<i,aj<ai)fi=max{fj+1}(j<i,aj<ai)
LCS:
fi,j=max⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪fi−1,jfi,j−1fi−1,j−1+1(ai=bi)⎫⎭⎬⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪fi,j=max{fi−1,jfi,j−1fi−1,j−1+1(ai=bi)}
我们将其融合一下就变成了
fi,j=max{fi−1,k}+1(k<j,bk<ai)fi,j=max{fi−1,k}+1(k<j,bk<ai)
于是我们就得到了一个TLE方程,然后因为每次k的范围只多了一个选项,于是我们就每次用变量计算最大就好了,于是 O(n2)O(n2)的算法就出来了。
code
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,a[3001],b[3001],f[3001][3001],val;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
scanf("%d",&b[i]);
for(int i=1;i<=n;i++)
{
val=0;//统计答案的变量
for(int j=1;j<=n;j++)
{
if(a[i]==b[j]) f[i][j]=val+1;
else f[i][j]=f[i-1][j];//动态转移
if(b[j]<a[i]) val=max(val,f[i-1][j]);//更新最大值
}
}
val=0;
for(int i=1;i<=n;i++) val=max(val,f[n][i]);
printf("%d",val);
}