虽然我在这个题没有拿到很好的分数,但是因为思路想了很久,所以还是想记录一下
这个题其实就是找最长递增序列,用正常的动态规划思路可以求出长度,但是还要记录这个序列、求字典序最小的,这就有点抠门
首先处理一下输入,用这个正则表达式可以匹配“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,其它都是“运行超时”