• 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;
    }
    
    

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

  • 相关阅读:
    使用Shell脚本查找程序对应的进程ID,并杀死进程
    转,mysql快速保存插入大量数据一些方法总结
    L2TP/IPSec一键安装脚本
    全文搜索引擎 Elasticsearch 入门教程
    vmware设置扩大硬盘后如何在linux内容扩容
    Java序列化说明
    GIT常用命令
    java中的CAS
    Class.forName()用法详解
    Java用pdfbox或icepdf转换PDF为图片时,中文乱码问题
  • 原文地址:https://www.cnblogs.com/Hydrogen-Helium/p/11737993.html
Copyright © 2020-2023  润新知