[2017纪中10-25]凤凰院修真 LCIS最长公共上升子序列

来源:互联网 发布:淘宝童鞋女孩冬季筒靴 编辑:程序博客网 时间:2024/06/07 08:01

题面
f[i][j]表示a序列考虑到i,b序列考虑到j且b[j]必须选的最长长度。
a[i]!=b[j]时,f[i][j]=f[i-1][j]。
那么当a[i]==b[j]时,f[i][j]=max{f[i-1][k]}+1,k

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int n,m,a[5010],b[5010],f[5010][5010],mx[5010],d[5010];struct node{    int x,y;}zy[5010][5010],id[5010],im[5010];int main(){    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 i=1;i<=n;i++)    {        memset(d,0x3f,sizeof(d));        d[0]=0;        for(int j=1;j<=m;j++)        {            if(a[i]==b[j])            {                int t=lower_bound(d,d+m+1,a[i])-d-1;                f[i][j]=f[id[t].x][id[t].y]+1;                zy[i][j]=id[t];            }            if(d[mx[j]]>b[j])            {                d[mx[j]]=b[j];                id[mx[j]]=im[j];            }            if(f[i][j]>mx[j])            {                mx[j]=f[i][j];                im[j].x=i;im[j].y=j;            }        }           }    int mxlen=0;    node fm;    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)            if(f[i][j]>mxlen)            {                mxlen=f[i][j];                fm.x=i;fm.y=j;            }    printf("%d\n",mxlen);           int ans[5010],top=0;    for(node t=fm;t.x>0&&t.y>0;t=zy[t.x][t.y])        ans[++top]=a[t.x];    for(int i=mxlen;i>=1;i--)        printf("%d ",ans[i]);       return 0;}

正解代码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int n,m,a[5010],b[5010],f[5010][5010],mx[5010],d[5010];struct node{    int x,y;}zy[5010][5010];int main(){    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 i=1;i<=n;i++)    {        int k=0;        for(int j=1;j<=m;j++)            if(a[i]==b[j])            {                f[i][j]=f[i][k]+1;                zy[i][j].x=i;zy[i][j].y=k;            }            else            {                f[i][j]=f[i-1][j];                zy[i][j].x=i-1;zy[i][j].y=j;                if(a[i]>b[j]&&f[i][j]>f[i][k]) k=j;            }       }    int mxlen=0;    node fm;    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)            if(f[i][j]>mxlen)            {                mxlen=f[i][j];                fm.x=i;fm.y=j;            }    printf("%d\n",mxlen);           int ans[5010],top=0;    for(node t=fm;t.x>0&&t.y>0;t=zy[t.x][t.y])        if(t.y>zy[t.x][t.y].y)ans[++top]=a[t.x];    for(int i=mxlen;i>=1;i--)        printf("%d ",ans[i]);    return 0;}
原创粉丝点击