zoukankan      html  css  js  c++  java
  • 1458 Common Subsequence

    最简单的LIS;

    设字符串为 a = acc  b = cc

    则dp数组为

    0 0

    1 1

    1 2

    b[0] = a[1], b[1] = a[1] 防止这里算两个

    要清楚的是 怎么不重复计算 也就是dp[1]的计算

    首先dp[1][0] = 1;

    再处理 dp[1][1], 因为 b[1] = a[1], 它是可以加一的 加哪一个呢? 要是直接继承左边的 选择dp[1][0] + 1 就会发生重复计算 因为b[0] = a[1], dp[1][0]已经是加上了一个共同字符的值

    解决方法是 选择 dp[0][0]  + 1 也就是继承上一轮的dp值, 因为上一轮只搞了a[0], 没有倒腾a[1], 即使 b[0] = a[1]也没有算进去, 所以避免了重复, 以此类推

    写成滚动数组

    #include <stdio.h>
    #include <iostream>
    #include <cstring>
    #include <vector>
    #include <queue>
    #include <set>
    #include <sstream>
    #include <algorithm>
    const int si = 1e4;
    using namespace std;
    int dp[2][si];
    
    int main() {
        string sss, a, b;
        while (getline(cin, sss)) {
            stringstream ss(sss);
            ss >> a;
            ss >> b;
            fill(dp[0], dp[0] + 2 * si, 0);
            int sa = a.size(), sb = b.size();
            int e = 0;
            for (int i = 1; i <= sa; i++) {
                for (int j = 1; j <= sb; j++) {
                    dp[e][j] = max(dp[1 - e][j], dp[e][j - 1]);
                    if (b.at(j - 1) == a.at(i - 1)) {
                        dp[e][j] = max(dp[1 - e][j - 1] + 1, dp[e][j]);
                        //dp[1 - e][j - 1]是j-1在上一层没有匹配第i-1个的 所以不会重复计算
                    }
                }
                e = 1 - e;
            }
            cout << dp[1 - e][sb] << endl;
        }
        return 0;
    }
  • 相关阅读:
    家庭记账本(七+每周总结)
    家庭记账本(六)
    家庭记账本(五)
    家庭记账本(四)
    家庭记账本(三)
    家庭记账本(二)
    家庭记账本(一)
    2021.2.14(每周总结)
    2021.2.13
    文件上传时报错in a frame because it set 'X-Frame-Options' to 'deny'.
  • 原文地址:https://www.cnblogs.com/smatrchen/p/10585532.html
Copyright © 2011-2022 走看看