zoukankan      html  css  js  c++  java
  • 旅行⭐

    题面

    爱丽丝和鲍勃想去旅行。

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

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

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

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

    该地区共有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;
    }
    
  • 相关阅读:
    主成分分析PCA(1)
    机器人操作系统入门(七)rospy客户端库
    线性代数的本质(Essense of Linear Algebra)——3Blue1Brown
    机器人操作系统入门(六)roscpp客户端库
    《机器人操作系统(ROS)浅析》肖军浩译
    机器人操作系统入门(五)常用工具
    Python学习(八)Matlab和Numpy异同
    机器人操作系统入门(四)ROS通信架构
    机器人操作系统入门(三)ROS通信架构
    机器人操作系统入门(二)ROS文件系统
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/12839195.html
Copyright © 2011-2022 走看看