zoukankan      html  css  js  c++  java
  • 51nod--1006 最长公共子序列Lcs (动态规划)

    题目:

    给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的)。
    比如两个串为:

    abcicba
    abdkscab

    ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列。
    Input
    第1行:字符串A
    第2行:字符串B
    (A,B的长度 <= 1000)
    Output
    输出最长的子序列,如果有多个,随意输出1个。
    Input示例
    abcicba
    abdkscab
    Output示例
    abca

    分析:

    这次要打印LCS, 所以需要额外的处理;
    一般LCS , 我们知道 Dp[i][j] 的值只会来自 Dp[i-1][j], Dp[i][j-1], Dp[i-1][j-1];
    而我们知道, 当 Dp[i][j] == Dp[i-1][j-1] 时, 就是两个字符相等的时候。
    所以我们只需要从 Dp[n][m] 回溯就好了

    实现:

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int maxn  = 1000 + 131;
    
    char s[maxn], t[maxn];
    int Dp[maxn][maxn];
    
    void Solve() {
        // Dp 部分
        int n = strlen(s),
            m = strlen(t);
        memset(Dp, 0, sizeof(Dp));
        for(int i = 0; i < n; ++i)
            for(int j = 0; j < m; ++j) {
                if(s[i] == t[j])
                    Dp[i+1][j+1] = Dp[i][j] + 1;
                else 
                    Dp[i+1][j+1] = max(Dp[i][j+1], Dp[i+1][j]);
            }
        // 回溯部分
        int i = n, j = m;
        stack<char> Ans;
        while(Dp[i][j]) {
            if       (Dp[i][j] == Dp[i-1][j]) i--;
            else if  (Dp[i][j] == Dp[i][j-1]) j--;
            else     Ans.push(s[i-1]), i--, j--;
        }
        while(Ans.empty() == false) {
            cout << Ans.top();
            Ans.pop();
        }
    }
    
    int main() {
        while(cin >> s >> t) {
            Solve();
        }
        return 0;
    }
  • 相关阅读:
    MySQL在windows上的安装步骤
    k-均值聚类算法
    python2和python3中filter函数
    解决mysql出现的问题#1055
    python高级编程1
    二叉树
    Python常用算法(二)
    Python常用算法(一)
    Java蓝桥杯--入门训练(1) Fibonacci数列
    java基础--for-跑步运动
  • 原文地址:https://www.cnblogs.com/aoxuets/p/5506833.html
Copyright © 2011-2022 走看看