zoukankan      html  css  js  c++  java
  • CF10D LCIS[动态规划]

    LCISLCIS


    Description

    链接
    给出两个长度分别为N,MN, M的数列, 求最长上升公共子序列的长度


    Solution

    设阶段为 i,ji, j 表示第一个串前ii个元素与第二个串前jj个元素 LCISLCIS
    根据LCSLCS的转移方程, 初步得出 :

    if(Ai==Bi)if(A_i == B_i). dp[i,j]=dp[i1][j1]+1dp[i, j] = dp[i-1][j-1] + 1
    elseelse. dp[i,j]=max(dp[i1][j],dp[i][j1])dp[i, j] = max(dp[i-1][j], dp[i][j-1])

    但这是错误的, 因为还要求单调递增, 于是为了方便转移, 需要额外一个维度来保证正确性?
    dp[i,j,k]dp[i, j, k] 表示第一个串前ii项与第二个串前jjLCISLCIS且最后一个元素为 kk
    可以初步得到

    if(Ai==Bj)if(A_i == B_j). dp[i,j,Bj]=dp[i1,j1,Bp]+1dp[i, j, B_j] = dp[i-1, j-1, B_p]+1. {p(0,j),Bp<k}{p∈(0, j), B_p <k}
    elseelse. dp[i,j,k]=dp[i1,j,k]dp[i, j, k] = dp[i-1, j, k]

    然而上方的愚蠢行为不知道会引起多少人笑话…
    完全可以不要第3维:

    if(Ai==Bj)if(A_i == B_j). dp[i,j]=dp[i1,p]+1dp[i, j] = dp[i-1, p]+1. {p(0,j),Bp<k}{p∈(0, j), B_p <k}
    elseelse. dp[i,j]=dp[i,j1]dp[i, j] = dp[i, j-1]

    由于最后要输出方案, 所以使用PrePre数组记录最优转移来源, 最后递归输出即可


    Code

    #include<bits/stdc++.h>
    #define reg register
    
    const int maxn = 505;
    
    int N;
    int M;
    int A[maxn];
    int B[maxn];
    int dp[maxn][maxn];
    int Pre[maxn][maxn];
    
    void print(int x){
            if(!x) return ;
            print(Pre[N][x]);
            printf("%d ", B[x]);
    }
    
    int main(){
            scanf("%d", &N);
            for(reg int i = 1; i <= N; i ++) scanf("%d", &A[i]);
            scanf("%d", &M);
            for(reg int i = 1; i <= M; i ++) scanf("%d", &B[i]);
            for(reg int i = 1; i <= N; i ++){
                    int maxx = 0, pre = 0;
                    for(reg int j = 1; j <= M; j ++){
                            if(A[i] == B[j]){
                                    if(dp[i][j] < maxx + 1){
                                            dp[i][j] = maxx + 1;
                                            Pre[i][j] = pre;
                                    }
                            }
                            else{
                                    dp[i][j] = dp[i-1][j];
                                    Pre[i][j] = Pre[i-1][j];
                            }
                            if(B[j] < A[i] && maxx < dp[i-1][j]) maxx = dp[i-1][j], pre = j;
                    }
            }
            int Ans = 0, Ans_p = 0;
            for(reg int i= 1; i <= M; i ++)
                    if(Ans < dp[N][i]) Ans = dp[N][i], Ans_p = i;
            printf("%d
    ", Ans);
            print(Ans_p);
            return 0;
    }
    
  • 相关阅读:
    XML 加密、解密
    word 转 pdf
    PowerDesigner(PowerDesigner15.1.0.2850)下载、安装以及破解
    SQL 2005 18456
    SQL 2005端口的修改
    SQL——统计查询
    由于启动用户实例的进程时出错,导致无法生成 SQL Server 的用户实例 解决办法
    ASP.NET MVC中Model View Controller的开发顺序
    使用Windows身份验证的Intranet网站安全管理 Windows Authentication
    ASP.NET web.config中数据库连接字符串connectionStrings节的配置
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822655.html
Copyright © 2011-2022 走看看