• UVA10066 【The Twin Towers】


    题目大意:给定两个序列,求他们的最长公共子序列,题目多测。

    考虑到这道题的数据范围比较小,(Nleq100),所以我们采用(n^2)的朴素方法即可。你觉得我会告诉你我不会nlogn的做法吗?!

    我们定义状态(f[i][j])表示第一个串枚举到第(i)位,第二个串枚举到第(j)位时的最长公共子序列长度。

    考虑如何转移,我们分情况讨论:

    • (a[i-1]==b[i-1])时,考虑更新公共元素,显然此时的(f[i][j]=f[i-1][j-1]+1)

    • 否则,我们考虑继承,那么(f[i][j])就应取(f[i-1][j])(f[i][j-1])中最大值。

    由于我们转移的时候需要枚举串(a)和串(b)的长度,所以这个的复杂度是(O(n^2))的。

    最后,注意你的输出格式……

    code:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define max(a, b) ((a) > (b) ? (a) : (b))
    // 对,我觉得using namespace std慢,所以没写
    int f[110][110], a[110], b[110];
    
    int main() {
        std::ios::sync_with_stdio(0); // 关闭cin的同步缓存流,加快速度
        int n, m, cnt = 0;
        while (std::cin >> n >> m && (n != 0 || m != 0)) {
            for (int i = 0; i < n; i++) std::cin >> a[i];
            for (int i = 0; i < m; i++) std::cin >> b[i];
            memset(f, 0, sizeof(f));
            for (int i = 1; i <= n; i++)
                for (int j = 1; j <= m; j++) {
                    if (a[i - 1] == b[j - 1]) f[i][j] = f[i - 1][j - 1] + 1;
                    else f[i][j] = max(f[i - 1][j], f[i][j - 1]); //核心转移方程
            }
            printf("Twin Towers #%d
    Number of Tiles : %d
    ", ++cnt, f[n][m]);
            puts(""); // 注意输出格式……
        }
        return 0;
    }
    
    

    完结撒花(*๓´╰╯`๓)

  • 相关阅读:
    LeetCode刷题之字符串
    LeetCode刷题之数组复习
    为什么要用移码来表示阶码(指数)呢?
    字节左移跟右移
    一个有趣的问题
    为什么对数组名取地址,得到的为整个数组的地址?
    在win10 64位下搭建汇编环境
    windows切换samba账号进行连接
    samba服务配置记录
    subversion钩子函数使用记录
  • 原文地址:https://www.cnblogs.com/Hydrogen-Helium/p/11737993.html
Copyright © 2020-2023  润新知