• 【简单dp】poj 2127 Greatest Common Increasing Subsequence【最长公共上升子序列】【模板】


    Sample Input

    5
    1 4 2 5 -12
    4
    -12 1 2 4

    Sample Output

    2
    1 4

    题目:给你两个数字序列,求出这两个序列的最长公共上升子序列。
    输出最长的长度,并打表输出。可能存在多种正确答案,故此题是special judge!

    分析:dp[i][j] : A[1...i]和B[1...j]的公共上升子序列中以B[j]为结尾的最长的长度。
    如果A[i] != B[j], 则dp[i][j]=d[i-1][j]; 也就是说当前这个A[i]是没效用的。
    如果A[i] = B[j], 则dp[i][j]=max( dp[i][k]+1 ),其中 k<j 且 A[i]>B[k]
    时间复杂度O(n^2)

    注意:
    n1 n2位两个序列的长度,
    A[] B[]为两个序列数组,
    ans 全局变量 最长公共子序列的长度值
    lcis 最长公共上升子序列 打表存储

    代码:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <math.h>
    #include <iostream>
    #include <string>
    #include <algorithm>
    
    using namespace std;
    
    int n1, n2;
    int A[510], B[510];
    int dp[510][510];
    int pre[510][510];
    int lcis[510];
    int ans;
    
    void get_LCIS()
    {
        memset(dp, 0, sizeof(dp));
        memset(pre, 0, sizeof(pre));
        int i, j;
        for(i=1; i<=n1; i++){
            int k=0;
            for(j=1; j<=n2; j++){
                if(A[i] != B[j]) dp[i][j]=dp[i-1][j];
                if(A[i]>B[j] && dp[i][j]>dp[i][k]) k=j;
                if(A[i]==B[j]){
                    dp[i][j]=dp[i][k]+1;
                    pre[i][j]=k;
                }
            }
        }
        ans=-1;
        int x=n1, y=0;
        for(i=1; i<=n2; i++){
            if(dp[n1][i]>ans){
                ans=dp[n1][i]; y=i;
            }
        }
        int cnt=1;
        while(dp[x][y]){
            if(A[x] != B[y]) x--;
            else{
                lcis[ans-cnt]=B[y];
                cnt++;
                y=pre[x][y];
            }
        }
    }
    
    int main()
    {
        scanf("%d", &n1);
        for(int i=1; i<=n1; i++) scanf("%d", &A[i]);
        scanf("%d", &n2);
        for(int i=1; i<=n2; i++) scanf("%d", &B[i]);
    
        get_LCIS();
        printf("%d
    ", ans );
        for(int i=0; i<ans; i++)
            printf("%d%c", lcis[i], i==ans-1?'
    ':' ');
    
        return 0;
    }
    

  • 相关阅读:
    断开/删除 SVN 链接(.svn)的几种方法
    Android 中 ListView 常用属性合集
    Android 中 GridView 常用属性合集
    LeetCode-387-字符串中的第一个唯一字符
    LeetCode-374-猜数字大小
    LeetCode-290-单词规律
    LeetCode-278-第一个错误的版本
    LeetCode-383-赎金信
    LeetCode-367-有效的完全平方数
    LeetCode-350-两个数组的交集 II
  • 原文地址:https://www.cnblogs.com/yspworld/p/4713187.html
Copyright © 2020-2023  润新知