CF10D LCIS
Link
设\(f_{i,j}\)为只考虑\(a_{1\sim i}\)并且以\(b_j\)结尾的LCIS。
转移方程很好写
\(f_{i,j}=f_{i-1,j}(a_i\neq b_j)\)
\(f_{i,j}=\max\limits_{k\in[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\n",f[n][k]);
if(f[n][k]) print(n,k);
}