Link
设(f_{i,j})为只考虑(a_{1sim i})并且以(b_j)结尾的LCIS。
转移方程很好写
(f_{i,j}=f_{i-1,j}(a_i
eq b_j))
(f_{i,j}=maxlimits_{kin[1,j)}([b_k<a_i]f_{i-1,k})+1)
(g_{i,j})为它是从哪个(j)转移过来的。
上面的转移我们可以对每一维(i)实时记录一个最优的(k)。这样就可以做到(O(n^2))了。
#include<bits/stdc++.h>
using namespace std;
const int N=507;
int f[N][N],g[N][N],a[N],b[N];
int read(){int x;scanf("%d",&x);return x;}
void print(int i,int j)
{
if(!i) return ;
print(i-1,g[i][j]);
if(g[i][j]^j) printf("%d ",b[j]);
}
int main()
{
int n,m,i,j,k;
for(n=read(),i=1;i<=n;++i) a[i]=read();
for(m=read(),i=1;i<=m;++i) b[i]=read();
for(i=1;i<=n;++i)
for(j=1,k=0;j<=m;++j)
if(a[i]==b[j]) f[i][j]=f[i-1][k]+1,g[i][j]=k;
else
{
f[i][j]=f[i-1][j],g[i][j]=j;
if(b[j]<a[i]&&f[i-1][j]>f[i-1][k]) k=j;
}
for(k=0,i=1;i<=m;++i) if(f[n][i]>f[n][k]) k=i;
printf("%d
",f[n][k]);
if(f[n][k]) print(n,k);
}