Acwing:旅行(DP+LCS求总方案数 Python)

爱丽丝和鲍勃想去旅行。

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

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

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

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

该地区共有 26 个城市,用小写字母 az 表示。

输入格式

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

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

输出格式

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

每个路线列表占一行。

输入样例:

abcabcaa
acbacba

输出样例:

ababa
abaca
abcba
acaba
acaca
acbaa
acbca

注 :可能是Python运行较慢的原因 代码TLE 只能通过部分数据

import copy
str1 = input()
str2 = input()

len1 = len(str1)
len2 = len(str2)

table = [[0 for i in range(len2+1)]for j in range(len1+1)] # 和正常求LCS总数的方法对应的列表一样
ans = set()

def lcs(m,n) : # 求LCS总数的方法
    global table
    for i in range(1,m+1) :
        for j in range(1,n+1) :
            if str1[i-1] == str2[j-1] :
                table[i][j] = table[i-1][j-1] + 1
            else :
                table[i][j] = max(table[i-1][j],table[i][j-1])
    return table[m][n]

def traceBack(m,n,target) : # target是当前答案串的逆序
    global table
    while m > 0 and n > 0 :
        if str1[m-1] == str2[n-1] : # 如果这个位置上的两个字符相同,那么就把这个字符加入到答案串的末尾
            target += str1[m-1]
            m -= 1
            n -= 1
        else : # 若不相同 找到 table[m-1][n] 和 table[m][n-1] 中的最大值 并修改m和n
            if table[m-1][n] > table[m][n-1] :
                m -= 1
            elif table[m-1][n] < table[m][n-1] :
                n -= 1
            else : # 若able[m-1][n] 和 table[m][n-1]相等 则需要递归处理两种情况
                traceBack(m-1,n,target)
                traceBack(m,n-1,target)
                return
    ans.add(target[::-1]) # 添加答案到集合中

length = lcs(len1,len2)  
traceBack(len1,len2,"")

ans = list(ans)
ans.sort() # 字典序输出

for item in ans :
    print(item)

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UESTC_KS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值