写在前面
⚠️写这份题解之前我是没有看过任何版本的题解,以下代码均是我独立AC后把代码记录到该题解内。
🚀代码提交后是能保证100%通关的,并且配有注释,可以放心食用。
C题 松散子序列🌟🌟🌟(10分)
题目描述
给定一个仅含小写字母的字符串 s ,假设 s 的一个子序列 t 的第 i 个字符 对应了原字符串中的第 pi 个字符。我们定义 s 的一个松散子序列为:对于 i > 1 总是有 pi − pi−1 ≥ 2 。设一个子序列的价值为其包含的每个字符的价值之和 ( a ∼ z 分别为 1 ∼ 26 ) 。
求 s 的松散子序列中的最大价值。
输入格式
输入一行包含一个字符串 s 。
输出格式
输出一行包含一个整数表示答案。
样例输入
azaazaz
样例输出
78
代码解析
s = [0] + list(input())
for i in range(1, len(s)): s[i] = ord(s[i]) - 96
dp = [0] * (len(s) + 1) # dp[i]表示前i个数的最大价值
dp[1] = s[1]
for i in range(2, len(s)):
# 第i个数不选的话从dp[i-1]直接递推过来,不选的话从dp[i-2]递推过来,满足选的数都至少间隔1个。
dp[i] = max(dp[i - 1], dp[i - 2] + s[i])
print(dp[len(s) - 1])
D题 管道🌟🌟🌟(10分)
题目描述
有一根长度为 len 的横向的管道,该管道按照单位长度分为 len 段,每一段的中央有一个可开关的阀门和一个检测水流的传感器。
一开始管道是空的,位于 Li 的阀门会在 Si 时刻打开,并不断让水流入管道。
对于位于 Li 的阀门,它流入的水在 Ti (Ti ≥ Si) 时刻会使得从第 Li−(Ti−Si) 段到第 Li + (Ti − Si) 段的传感器检测到水流。 求管道中每一段中间的传感器都检测到有水流的最早时间。
输入格式
输入的第一行包含两个整数 n, len,用一个空格分隔,分别表示会打开的阀门数和管道长度。
接下来 n 行每行包含两个整数 Li , Si,用一个空格分隔,表示位于第 Li 段 管道中央的阀门会在 Si 时刻打开。
输出格式
输出一行包含一个整数表示答案。
样例输入
3 10
1 1
6 5
10 2
样例输出
5
代码解析
这道题满足答案的二段性,也是最大值最小化问题,可以用二分法求解。
n, ll = map(int, input().split())
a = []
for _ in range(n):
a.append(list(map(int, input().split())))
def check(ans):
res = [] # res存储管道的灌溉区间
for i in range(n):
if ans < a[i][1]: continue
l = max(1, a[i][0] - (ans - a[i][1]))
r = min(ll, a[i][0] + (ans - a[i][1]))
res.append([l, r])
res.sort()
# 如果最左起点不能灌溉到1管道则False
if res[0][0] > 1: return False
rr = res[0][1] # 初始化最右灌溉区域
# 合并区间
for i in range(1, len(res)):
# 如果该区间和上一区间没有交集且不连续则False
if res[i]