zoukankan      html  css  js  c++  java
  • 杂题

    题意

    给定一个(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))

  • 相关阅读:
    Hugo搭建的博客删除文章事宜
    [GIT] Git学习笔记
    VS Code: 解决安装code-runner扩展run后无法在只读编辑器下编辑
    c/c++结构体总结
    恢复U盘做启动盘后的容量
    Manjaro安装Mysql
    win10环境下安装manjaro kde(双系统)
    IDEA设置编辑区主题
    IDEA设置主体、窗体及菜单的字体大小
    IDEA设置项目文件编码
  • 原文地址:https://www.cnblogs.com/Grice/p/14928327.html
Copyright © 2011-2022 走看看