题目描述
解题思路
ps:思路是我看了大佬的题解后自己的理解,自己给自己捋清楚思路。
1.设置输入,将字符串输入
2.因为输入的是字符,但要找出字符的最大价值,所以先将字符串转化成对应的数值。
这时候就要用到ord函数,这个函数用于返回表示给定字符的Unicode代码点的整数。就是把字符转成ASCII码。小写字母 a 从 97 开始,要想让 a 的数值是 1,就要对96取余,得到结果就是1,后面的字符同理,这样就能得到字母 a ~ z 对应的数值是1 ~ 26。把字符转换成数字后存到 s_list[ ]列表中。
3.定义我们要得到的子序列的数值 t[ ], 长度为 len(s) + 1 ,因为条件说 pi- pi-1>2,所以循环时要从1开始才能保证这个条件成立,如果 t [ ]列表长度不加 1 数据会越界。先把列表中的数值都设置为0,在后续的循环中我们进行相加比较后再进行重新赋值修改。
4.开始 for 循环:
循环变量 i 从1 开始:就先把 s 字符的第一个字符对应的数值添加进 t [ 1 ]。
i > 1时:将 s_list[i-1]+t[i-2] 与 t[i-1] 进行比较,找出较大的值,添加到 t[ i ] 中。
如图所示,将数值加起来就就是该字符串对应的子串,通过数值不断地相加,找出最大的数值。
我看的那个大佬的代码多写了一种 i == 2时的情况,其实也可以不写,因为 t[0] = 0,最后是s_list[0]与s_list[1]比较,都一样。
我已经尽可能的说明白这个过程了,还是自己根据题目给出的例子自己动手算一算,这样会对动态规划的理解更深刻一些。
代码实现
s = input()
s_list = [ord(i) % 96 for i in s]
# for i in s: # 这三行代码直接用上面的列表推导式实现了
# m = ord(i) % 96 # 对简化代码非常有帮助
# s_list.append(m)
t = [0 for j in range(len(s)+1)]
for i in range(1, len(s)+1):
if i == 1:
t[i] = s_list[0]
# elif i == 2: # 这种i==2的情况可写可不写,因为else中也包含了第二种情况
# t[i] = max(s_list[1], s_list[0])
else:
t[i] = max(s_list[i-1]+t[i-2], t[i-1])
print(t[-1])
最后实现的代码也是很简单的,我们自己思考也是很简单的,一看就能看出来三个z组成的子串对应的数值最大,难的就是将人的思维转化成代码,告诉机器应该怎么思考怎么算。在学习算法的时候真的需要多思考,多动手。