【小优化】O(nlog(n))求单调不降(递增)序列

用到的时候才发现这么普遍的知识点还有遗漏。orz

关于O(n^2)求单调不降序列有一个很朴素的想法,每一次新加一个数,在前面找到比他小(或相等)的f[i]值最大的那个数并把这个新加的那个数的f[i]值+1(f[i]值表示可以作为不降序列的第几个),常数严格为1/2。

我们对O(n^2)的算法进行一些优化。我们引入一个数组F[] ,这个数组的意义: F[i]表示这个数F[i]是在所有能够在原数列(直到目前讨论的位置)中作为单调不降序列的第i个数中的最小的那一个数。

什么意思呢?例如我们有一个数列 { 1,5,2,4 },我们一个一个讨论。先直接将F[1]设定为1,++cnt1(cnt为单调不降序列长度),然后讨论到2,发现比F[cnt]大,++cnt2,F[2]设定为5。讨论到第3个,发现比F[cnt]小,那么我们在前面一个个找到第一个比2大的数,我们找到了F[2],我们将F[2]刷新为2。这意味着可以作为单调不降序列的第二位最小的数为2,(实际上有两个序列{1,5}{1,2}),再然后我们发现我们又可以++cnt==3,F[3]为4了。

如果我们暴力找出F[i]比他大的第一个数,我们可以发现其最坏情况也就达到朴素O(n^2)的常数情况,实际上常数要小很多,也可以水过很多数据。但是我们很容易发现F[]数组是具有单调性的啊,那么我们是不是可以直接二分查找直接找出来呢?是的,再加上二分查找,时间复杂度也就优化到了O(nlog(n))。

代码自己实现吧,实现起来很简单(日后有时间加上代码)

 

posted @ 2018-05-25 13:23  Newuser233  阅读(29)  评论(0)    收藏  举报