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);
}
posted @ 2019-10-27 22:25  Shiina_Mashiro  阅读(194)  评论(0编辑  收藏  举报