• 旅行⭐


    题面

    爱丽丝和鲍勃想去旅行。

    他们每个人制定了一条旅行路线,每条路线包含一个按给定顺序访问的城市列表,一个城市可能会多次出现在同一路线中。

    因为他们想要一起去旅行,所以必须在旅行路线上达成一致。

    他们两个都不想改变他们的路线上的城市顺序或者在路线上额外添加城市。

    因此,他们只能移除各自路线中的一些城市,使得旅行路线达成一致,并且尽可能的长。

    该地区共有26个城市,用小写字母’a’到’z’表示。

    输入格式

    输入包含两行,第一行是爱丽丝的路线城市列表,第二行是鲍勃的路线城市列表。

    每个列表由1到80个小写字母组成,其间没有空格。

    输出格式

    按升序顺序输出所有满足条件的路线列表。

    每个路线列表占一行。

    输入样例:

    abcabcaa
    acbacba
    

    输出样例:

    ababa
    abaca
    abcba
    acaba
    acaca
    acbaa
    acbca
    

    题解

    最长串不是难题

    f[i][j] 到a的前i个字符, b的前j个字符的最长串长度

    f[i][j] = f[i - 1][j - 1] + (a[i] == a[j]);

    f[i][j] = max(f[i][j], max(f[i - 1][j], f[i][j - 1]));

    主要是回溯问题, 写了个简单的的dfs, 超时了

    然后优化用set存状态,还是超时,首先看一下dfs状态

    dfs(int x, int y, int k) 在a的前x个字符,b的前y个字符找第k个字符

    我们发现

    当选择的字符一样时, 选择字符的位置越靠近x,y越优,

    可以包含后面同样时相同字符时的情况,

    所以直接找距离 x 和 y 最近的字符a的位置即可;

    那就再弄个数组 fa[i][j] 表示a字符串前i个字符中字母j + ‘a’最近出现的位置

    if (a[i] - ‘a’ == j) fa[i][j] = i;
    else fa[i][j] = f[i - 1][j];

    fb[i][j] 同理

    复杂度最坏的话应该是 O(26 * lena + 26 * lenb + lena * lenb + min(lena, lenb) * 26 * 2)

    (也有可能都算错了,瞎算的)

    #include <bits/stdc++.h>
    #define pb emplace_back
    using namespace std;
    
    const int maxn = 81;
    
    char a[maxn], b[maxn], ans[maxn];
    int f[maxn][maxn], fa[maxn][26], fb[maxn][26];
    vector<string> ve;
    
    void dfs(int x, int y, int k)
    {
        if (!k) { ve.pb(string(ans + 1)); return; }
        for (int i = 0; i < 26; ++i)
        {
            int a = fa[x][i], b = fb[y][i];
            if (min(a, b) < k || f[a][b] != k) continue;
            ans[k] = 'a' + i;
            dfs(a- 1, b - 1, k - 1);
        }
    }
    
    int main()
    {
        cin >> a + 1 >> b + 1;
        int lena = 1, lenb = 1;
        
        for (int& i = lena; a[i]; ++i)
            for (int j = 0; j < 26; ++j)
                if (a[i] == j + 'a') fa[i][j] = i;
                else fa[i][j] = fa[i - 1][j];
                
        for (int& i = lenb; b[i]; ++i)
            for (int j = 0; j < 26; ++j)
                if (b[i] == j + 'a') fb[i][j] = i;
                else fb[i][j] = fb[i - 1][j];
                
        for (int i = 1; a[i]; ++i)
            for (int j = 1; b[j]; ++j)
            {
                f[i][j] = f[i - 1][j - 1] + (a[i] == b[j]);
                f[i][j] = max(f[i][j], max(f[i][j - 1], f[i - 1][j]));
            }
            
        dfs(lena - 1, lenb - 1, f[lena - 1][lenb - 1]);
        
        sort(ve.begin(), ve.end());
        for (int i = 0; i < ve.size(); ++i) cout << ve[i] << '
    ';
        return 0;
    }
    
  • 相关阅读:
    elasticsearch 安装,以及遇到的问题总结
    Linux/unix 查看端口占用
    openresty 安装
    Hadoop 系列文章(三) 配置部署启动YARN及在YARN上运行MapReduce程序
    Hadoop 系列文章(二) Hadoop配置部署启动HDFS及本地模式运行MapReduce
    Hadoop 系列文章(一) Hadoop 的安装,以及 Standalone Operation 的启动模式测试
    Linux 防火墙相关
    Linux 修改默认的 yum 源
    普通用户开放 sudo 权限
    大数据所有环境变量
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/12839195.html
Copyright © 2020-2023  润新知