题意
给定一个(n)阶随机的排列,再给定(K),求最长的子序列的长度,满足有至多(K)对相邻元素中左边的大。
(nle 50000)
做法
有一个显然的做法,(f_{i,k})为以(i)结尾,有(k)个特殊对的最长长度,有:
[f_{i,k}=1+max(f_{j,k-[a_j< a_i]})
]
可以维护(K)棵线段树做到(O(Kcdot nlog n)),空间复杂度(O(Kcdot n))。
有如下减少转移的条件,可以忽略(j)对(i)的转移
(1)若(a_j< a_i),且存在(p),满足(j< p< i,a_j< a_p< a_i)。
(2)若(a_j> p_i),且存在(p),满足(j< p< i),(a_p< a_i)或(a_j< a_p)。
对于(1),转移到(i)的(j)是:忽略掉(> a_i)的数后的后缀最大值的位置。
对于(2),转移到(i)的(j)是:找到最大的(p< i),满足(a_p< i),对于((p,i))中,忽略(< a_i)的数后的后缀最大值的位置。
由于排列是随机的,有效的转移位置集合只有(O(log n)),同样可以做到(O(Kcdot nlog n))。
假设整个序列特殊对的数量有(C)个,若(Cle K),那么答案显然是整个排列。
否则,显然最优解是选择一个恰有(K)个特殊对的子序列。
观察:由于排列是随机的,(K)对在排列中的位置期望是均匀的。
也就是,在位置(i)时。最优子序列必须具有近似(Kcdot frac{i}{n})个特殊对。
因此,我们设一个阈值(B),在每个位置,仅存储(O(B))个状态,那么这部分复杂度将降低为(O(Bcdot nlog n)),空间复杂度降为(O(Bcdot n))。
当然也可以用动态开点线段树,空间复杂度(O(Bcdot nlog n))。