zoukankan      html  css  js  c++  java
  • 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;
    }
    
    

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

  • 相关阅读:
    <img />标签 alt title
    ubuntu中rar与unrar用法详解
    vi及缩进设置
    ubuntu下读取数据库中文乱码解决
    ubuntu下phpstorm无法输入中文的解决办法
    ubuntu下mysqli_connect()显示未定义,mysqli_fetch_all()显示未定义 解决方法
    权限控制
    NULL
    ubuntu下chromium 安装flash player
    手把手教你把Vim改装成一个IDE编程环境(图文)
  • 原文地址:https://www.cnblogs.com/Hydrogen-Helium/p/11737993.html
Copyright © 2011-2022 走看看