Jzoj5424 凤凰院凶真

来源:互联网 发布:selenium js click 编辑:程序博客网 时间:2024/06/08 08:37

给你两个序列A和B,求出他们的最长公共上升子序列并输出方案

动态规划,我们假设f[i][j]表示A处理到第i位,B处理到第j位时的长度

那么显然,若A[i]=B[j],那么f[i][j]=max{f[i-1][k]}+1,否则f[i][j]=f[i-1][j]

我们再记一个g[i][j]表示f[i][j]是从哪里转移过来的,记上面那个k即可

到时候直接倒序递归按照g[i][j]输出,若g[i][j]=0那么就--i

#pragma GCC optimize("O3")#pragma G++ optimize("O3")#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int f[5010][5010],g[5010][5010],a[5010],b[5010],n,m;void print(int i,int j){if(j){while(i&&!g[i][j]) i--;print(i-1,g[i][j]);printf("%d ",b[j]);}}int main(){freopen("okarin.in","r",stdin);freopen("okarin.out","w",stdout);scanf("%d",&n);for(int i=1;i<=n;++i) scanf("%d",a+i);scanf("%d",&m);for(int i=1;i<=m;++i) scanf("%d",b+i);for(int k,i=1;i<=n;++i){k=0;for(int j=1;j<=m;++j){f[i][j]=f[i-1][j];if(a[i]==b[j]){f[i][j]=f[i-1][k]+1;g[i][j]=k;}if(a[i]>b[j]&&f[i-1][k]<f[i-1][j]) k=j;}}int j=0;for(int i=m;i;--i)if(f[n][i]>f[n][j]) j=i;printf("%d\n",f[n][j]);print(n,j);}