0
点赞
收藏
分享

微信扫一扫

蓝桥杯 [第11届决赛] 游园安排 Python 60分

先峰老师 2022-02-04 阅读 52

虽然我在这个题没有拿到很好的分数,但是因为思路想了很久,所以还是想记录一下

这个题其实就是找最长递增序列,用正常的动态规划思路可以求出长度,但是还要记录这个序列、求字典序最小的,这就有点抠门

首先处理一下输入,用这个正则表达式可以匹配“Lan”、“Qiao”、“B”这种字符串,用findall函数找到所有的这种字符串即可完成分组

import re

mode = re.compile(r"[A-Z][a-z]*")
origin = re.findall(mode, input())
# 将字符串切分成若干个元素
length = len(origin)

然后用一个n行2列的矩阵来记录状态,第1列表示前n行最长递增序列长度,第2列表示前n行最长递增序列 (字典序最小)

dp = [[1, origin[_]] for _ in range(length)]
# 初始化: 每个位置的初始长度1, 初始字符串只有对应位置元素
for idx in range(1, length):
    state, string = dp[idx]
    # 读取当前状态
    cur_ele = origin[idx]
    # 读取当前索引下的元素
    for last in range(idx):
        l_state, l_string = dp[last]
        # 读取前置状态
        l_ele = origin[last]
        # 读取对应前置状态索引对应的元素
        if l_ele < cur_ele:
            # < 运算符比较字典序,满足递增条件
            if l_state + 1 > state:
                # l_string + cur_ele的元素长度 > string的元素长度
                state = l_state + 1
                string = l_string + cur_ele
                # 启动状态转移
            elif l_state + 1 == state:
                # l_string + cur_ele的元素长度 == string的元素长度
                string = min([l_string + cur_ele, string])
                # 取字典序最小的字符串
    dp[idx] = [state, string]
    # 记录到dp矩阵中

然后在做状态转移的时候严格控制字典序最小就好了

考虑达到最大长度的序列可能有多个,所以还要:

1. 找到最大长度

2. 找到对应该长度的序列

3. 取字典序最小的输出

result = max(dp, key=lambda x: x[0])[0]
# 找到元素最长的长度
choose = []
for val, string in dp:
    if val == result:
        # 因为达到最大长度的元素有多个,所以要汇总、取字典序最小的
        choose.append(string)
print(min(choose))

最终得分60,其它都是“运行超时”

举报

相关推荐

0 条评论