题解 | #Redraiment的走法#

Redraiment的走法

https://www.nowcoder.com/practice/24e6243b9f0446b081b1d6d32f2aa3aa

# 这题的意思就是 往右找比自己大的,包括自己看看有多少个,找这样 一个 最大的个数。
# 就是 最长 升序 子序列 长度;
# 动态规划 和 二分法 都适合解答。
'''
二分思路: 思想:

原始数组为A, 建立一个辅助数组B, 变量end用来记录B数组末尾元素的下标

遍历A中的所有的元素 x = A[i]

如果x > B的末尾元素,则将x追加到B的末尾,end+=1
如果x < B的末尾元素,则利用二分查找 bisect_left(list,goal) ,寻找B中第一个大于x的元素,并用x进行替换 e.g. x= 4 B=[1,3,5,6] ==> B=[1,3,4,6]
遍历结束之后,B的长度则为最长递增子序列的长度
'''
# ````````````````````````````````````````````````````````````````````````````````
'''
动态规划法:  思想:

假设长度为n的数组 a0 a1 a2...an , 以 ai 元素结尾的最长递增子序列为 Li ,

则当 j<i<n 且 ai>aj ,遇到大的了就考虑修改 Li ,Li = max(Li, Lj + 1 ) ,由递推公式知道遍历方向从左到右, Li 的初始值为1。这里需要理解,为什么max()内部会有一个 Li ,因为即便是j 和 i 并不相邻, 随着j的增长, 每一次判断都会考虑 Li 是否需要修改;
注意: 递推公式的使用是有条件的,一定是当 遇到了 ai > aj 的情况才可能使用,因此并不是d的最大值一定发生在最后!!! 因为 可能后面一截并没有遇到增长的 a。
'''
# 综上来看,二分法解决 最长升序子序列 太过于巧妙不容易想到,优先考虑用动态规划方法解决;
num = int(input())
values = input().strip().split(' ')
values = list(map(int,values))
# print(values)
d = [1]*num
for i in range(num):
    for j in range(i+1):
        if values[i] > values[j]:
            d[i] = max(d[i],d[j]+1)
print(max(d))

        


全部评论

相关推荐

这是什么操作什么意思,这公司我服了...
斯派克spark:意思是有比你更便宜的牛马了
点赞 评论 收藏
分享
评论
点赞
4
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务