最长升/降子序列(高级)

最长上升子序列

       见【这儿(点击)】

最长下降子序列

                                                       奶牛慢跑

                                                                  时间限制: 1 Sec  内存限制: 128 MB

题目描述

有n(n<=100000)头奶牛在一个无穷长的小道上慢跑。每头奶牛的起点不同,速度也不同。小道可以被分成多条跑到。奶牛只能在属于自己的跑道上慢跑,不允许更换跑道,也不允许改变速度。如果要慢跑t(t<=1000000000)分钟,要保证在任何时候不会有同一跑道上的奶牛相遇,请问最少需要多少条跑道。奶牛开始在哪条跑道是可以随意设置的。

输入

输入格式:第一行两个整数n,t。

接下来的n行,每行包含两个整数,表示奶牛的位置和速度。位置是非负整数,速度是正整数。所有的奶牛的起点都不相同,按起点递增的顺序给出。

输出

输出格式:

最少的跑道数。

思路:

       如果两头奶牛在开始和结束时刻它们的相对位置交换了或者在终点相遇了,那么它们必须是位于两根跑道上。

所以,我们以奶牛开始的位置从左到右给它们编号为1~n,那么结束时,再来看它们的编号。此时,递减的编号序列都需要不同的跑道。所以,最长下降子序列的长度即是最少需要的跑道数量。

       所以本题就是一个求最长不上升子序列的题。但是,朴素的dp是O(N^2)的。我们需要用一点技巧来优化一下。
在终点时刻,从左到右依次读取奶牛的编号,并将编号放入一个单调递减的数组中。具体做法为:如果当前编号cowi小于数组中最后一个元素的值cowj ,则将cowi 加到数组末尾;否则,对数组进行二分查找,找到第一个小于cowi 的元素cowk ,将cowk 替换为cowi 。最后数组中的元素个数即为最长不上升子序列的长度。这个做法是O(NlogN)的。该单调数组的意义可以这样理解:arr[i]表示一个奶牛的编号,该编号为所有不上升子序列中排第i位的编号的最大值。

 

posted @ 2018-12-18 13:43  DD_XYX  阅读(50)  评论(0编辑  收藏  举报