最长公共子序列+最长递增子序列+最长递增公共子序列

来源:互联网 发布:java get set方法 编辑:程序博客网 时间:2024/05/17 06:32

//求最长公共子序列

int dp[maxn][maxn];int a[maxn],b[maxn];int main(){    int m,n;    scanf("%d %d",&m,&n);    for(int i=1; i<=m; i++)        scanf("%d",&a[i]);    for(int i=1; i<=n; i++)        scanf("%d",&b[i]);    memset(dp,0,sizeof(dp));    int ans=0,i,j;    for(i=1; i<=m; i++)    {        for(j=1; j<=n; j++)        {            if(a[i]==b[j])            {                dp[i][j]=dp[i-1][j-1]+1;            }            else                dp[i][j]=max(dp[i-1][j],dp[i][j-1]);        }    }    printf("%d\n",dp[m][n]);    return 0;}

//输出最长公共子序列

int dp[maxn][maxn];int d[maxn][maxn];int a[maxn],b[maxn],ans[maxn];int main(){    int m,n;    int i,j;    scanf("%d %d",&m,&n);    for(i=1; i<=m; i++)        scanf("%d",&a[i]);    for(i=1; i<=n; i++)        scanf("%d",&b[i]);    for(i=0;i<=m;i++)        dp[i][0]=0;    for(i=0;i<=n;i++)        dp[0][i]=0;    for(i=1; i<=m; i++)    {        for(j=1; j<=n; j++)        {            if(a[i]==b[j])            {                dp[i][j]=dp[i-1][j-1]+1;                d[i][j]=3;            }            else            {                if(dp[i-1][j]>=dp[i][j-1])                {                    dp[i][j]=dp[i-1][j];                    d[i][j]=2;                }                else                {                    dp[i][j]=dp[i][j-1];                    d[i][j]=1;                }            }        }    }    i=m,j=n;    int k=dp[m][n]-1;    while(k>=0&&i>0&&j>0)    {        if(d[i][j]==3)        {            ans[k--]=a[i];            i--;            j--;        }        else if(d[i][j]==2)            i-- ;        else if(d[i][j]==1)            j--;        else            break;    }    printf("%d\n",dp[m][n]);    for(i=0;i<dp[m][n];i++)        printf("%d ",ans[i]);    printf("\n");    return 0;}

//求最长上升子序列

int a[maxn],dp[maxn];int main(){    int m;    scanf("%d",&m);    for(int i=1;i<=m;i++)        scanf("%d",&a[i]);    int res=0;    for(int i=1;i<=m;i++)    {        dp[i]=1;        for(int j=1;j<i;j++)        {            if(a[j]<a[i])            {                dp[i]=max(dp[i],dp[j]+1);            }        }        res=max(res,dp[i]);    }    printf("%d\n",res);    return 0;}

//最长上升子序列优化(利用二分查找lower_bound()函数)
//查找优化到0(log(n))

int a[maxn],dp[maxn];#define INF 0x3f3f3fint main(){    int m;    scanf("%d",&m);    for(int i=0;i<m;i++)        scanf("%d",&a[i]);    memset(dp,INF,sizeof(dp));    for(int i=0;i<m;i++)    {        *lower_bound(dp,dp+m,a[i])=a[i];     }    printf("%d\n",lower_bound(dp,dp+m,INF)-dp);    return 0;}

//求最长递增公共子序列(时间复杂度为0(n^3))

int dp[maxn][maxn];   //dp[i][j]代表数组 a 前 i 个,数组 b 前 j 个且以 b[j] 为结尾的LCISint a[maxn],b[maxn];int main(){    int m,n;    int i,j;    scanf("%d %d",&m,&n);    for(i=1;i<=m;i++)        scanf("%d",&a[i]);    for(i=1;i<=n;i++)        scanf("%d",&b[i]);    memset(dp,0,sizeof(dp));    for(i=1;i<=m;i++)    {        for(j=1;j<=n;j++)        {            if(a[i]!=b[j])                dp[i][j]=dp[i-1][j];            else            {                for(int k=1;k<j;k++)                {                    dp[i][j]=max(dp[i][j],dp[i-1][k]+1);                }            }        }    }    int ans=0;    for(i=1;i<=n;i++)        ans=max(ans,dp[m][i]);    printf("%d\n",ans);    return 0;}

//最长递增公共子序列优化(时间上)

int dp[maxn][maxn];int a[maxn],b[maxn];int main(){    int m,n;    int i,j;    scanf("%d %d",&m,&n);    for(i=1;i<=m;i++)        scanf("%d",&a[i]);    for(i=1;i<=n;i++)        scanf("%d",&b[i]);    memset(dp,0,sizeof(dp));    for(i=1;i<=m;i++)    {        int maxx=0;        for(j=1;j<=n;j++)        {            if(a[i]>b[j]) maxx=max(maxx,dp[i-1][j]);   //标记dp[i-1][k]中的最大值            if(a[i]!=b[j])                dp[i][j]=dp[i-1][j];            else                dp[i][j]=maxx+1;        }    }    int ans=0;    for(i=1;i<=n;i++)        ans=max(ans,dp[m][i]);    printf("%d\n",ans);    return 0;}

//最长递增公共子序列优化(空间上)

int dp[maxn];int a[maxn],b[maxn];int main(){    int m,n;    int i,j;    scanf("%d %d",&m,&n);    for(i=1;i<=m;i++)        scanf("%d",&a[i]);    for(i=1;i<=n;i++)        scanf("%d",&b[i]);    memset(dp,0,sizeof(dp));    for(i=1;i<=m;i++)    {        int maxx=0;        for(j=1;j<=n;j++)        {            if(a[i]>b[j]) maxx=max(maxx,dp[j]);            if(a[i]==b[j]) dp[j]=maxx+1;        }    }    int ans=0;    for(i=1;i<n;i++)        ans=max(ans,dp[i]);    printf("%d\n",ans);    return 0;}
2 0