当前位置: 首页> 教育> 高考 > 永久二级域名分发平台_沈阳网站建设活动方案_长尾关键词爱站网_网站制作平台

永久二级域名分发平台_沈阳网站建设活动方案_长尾关键词爱站网_网站制作平台

时间:2025/8/19 10:58:57来源:https://blog.csdn.net/wniuniu_/article/details/146922078 浏览次数:0次
永久二级域名分发平台_沈阳网站建设活动方案_长尾关键词爱站网_网站制作平台

上面的这两个都可以直接用dp来写,但是dp的话复杂度是 n 2 n^2 n2,复杂度还是太大了

先从最长上升子序列说起

二分+贪心

我们可以维护一个到 a [ i ] a[i] a[i]的最长上升子序列,每次遇到一个新的数 x x x 就在刚刚的序列里面二分查找第一个大于等于 x x x 的位置,这里直接二分就行,如果序列的最大一个元素还是小于 x x x,那么我们的x就直接放到序列的最后面

[ 2 , 4 , 7 ] [2 , 4, 7] [2,4,7] 当前 x = 8, 那么8就可以直接插入序列的末尾就可以维护一个更长的上升序列

[ 2 , 4 , 7 ] [2 , 4, 7] [2,4,7] 当前 x = 5, 那么5应该插入到 7 的位置,这样可以维护一个长度相等,但是一个更优的序列

代码如下:

class Solution:def lengthOfLIS(self, nums: List[int]) -> int:g = []for x in nums:j = bisect_left(g,x)if j == len(g):g.append(x)else:g[j] = xreturn len(g)

如果是最长非递减子序列呢,这个就要求我们维护的序列中可以存在相同的元素
改进也很简单

# 上面的代码只用修改 bisect_left
# 改成 
j = bisect_right(g,x)

万能法:线段树或树状数组

我们可以直接定义 d p [ i ] dp[i] dp[i] 为以 a [ i ] a[i] a[i] 结尾的序列的最大长度,那么应该怎么转换呢

d p [ i ] = m a x ( d p [ j ] ) + 1 , j < i a [ j ] < a [ i ] dp[i] = max(dp[j])+1,j<i a[j]<a[i] dp[i]=max(dp[j])+1,j<ia[j]<a[i]
我们怎么找到所有索引在 i i i之前,且 a [ j ] < a [ i ] a[j] < a[i] a[j]<a[i] d p [ j ] dp[j] dp[j] 最大值呢

我们用到权值线段树,不用数组 a [ i ] a[i] a[i] 的下标索引 i i i 作为线段树的插入索引,而是用 a [ i ] a[i] a[i]的值作为索引, d p [ i ] dp[i] dp[i] 作为线段树中我们要维护的值,我们每次只要查询 [ 1 , a [ i ] ] [1,a[i] ] [1,a[i]] 之间的最大值就可以得到满足的最大的 d p [ j ] dp[j] dp[j],(注意,最长上升子序列是 [ 1 , a [ i ] − 1 ] [1,a[i]-1] [1,a[i]1],最长非递减子序列是 [ 1 , a [ i ] ] [1,a[i]] [1,a[i]]

注意一下update函数的更新细节

         if l==r:self.t[o] = max(self.t[o],x)  # 可能会重复更新
关键字:永久二级域名分发平台_沈阳网站建设活动方案_长尾关键词爱站网_网站制作平台

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: