zoukankan      html  css  js  c++  java
  • 斜率凸优化小结

    斜率凸优化小结

    前言

    很久以前考了一道叫做"林克卡特树"的题目( 还记得被八省联考支配的恐惧吗?)
    正解是用直线去切一个凸函数......
    当时并不是很会。然而(APIO)讲课竟然讲了并且卧槽我竟然还听懂了。
    所以就回来把这个坑给填了。

    斜率凸优化

    当遇到关于需要恰好选取(K)个的(DP)问题的时候,
    一般做法就是在(DP)数组上再设一维。这样做时间代价是(O(n))的。
    其实不如给每次选取加一个权值(C)
    那么每次选取就需要付出(C)的代价。所以(C)越大选的越少,(C)越小选的越多。
    所以?二分(C)即可。时间代价变为(O(logn))
    形象的来说,对于(DP)数组,取(E)个时的答案(best(E))是一个上凸的。
    所以我们用(f(x) = Cx)这条直线去切这个上凸包,直到(best(K)-KC)是最优的。
    那么此时选取的个数就是题目所需的(K)个了。
    下面给一张图(引用自cjfdf):

    例1:[APIO2014]序列分割

    题目戳这里
    可以发现,对于不在同一段的任意两个元素(a),(b),都对答案有(ab)的贡献。
    所以处理出前缀和(pre)
    那么转移:(f_{i,j} = max{f_{k,j-1} + pre_k * (pre_i - pre_k)})
    斜率优化不解释,复杂度(O(nK)),可以直接通过原题。
    如果(K leq 200) 变为(K leq n)呢? 直接斜率凸优化即可,复杂度(O(nlogK'))
    代码戳这里

    例2:[八省联考2018]林克卡特树lct

    题目戳这里
    本质上就是要选择出(K+1)条不相交的路径使它们的权值和最大。
    考虑树形(DP)。设(f_{u,j,0/1/2})分别表示(u)点的度数为(0/1/2)时的最优解。
    定义(Ans_{u,j})表示(max{f_{u,j,0/1/2}})
    转移:
    对于(f_{u,j,0})有:

    • (f_{u,j,0} = max{ f_{u,j-t,0} + Ans_{v,t} })

    对于(f_{u,j,1})有:

    • (f_{u,j,1} = max{ f_{u,j-t,1} + Ans_{v,t}})
    • (f_{u,j,1} = max{ f_{u,j-t,0} + f_{v,t,1} + Edge_{u,v}})
    • (f_{u,j,1} = max{ f_{u,j-t-1,0} + f_{v,t,0} + Edge_{u,v}})

    对于(f_{u,j,2})有:

    • (f_{u,j,2} = max{ f_{u,j-t,2} + Ans_{v,t}})
    • (f_{u,j,2} = max{ f_{u,j-t+1,1} + f_{v,t,1} + Edge_{u,v}})

    上述转移复杂度(O(nK^2)),不够优秀。
    发现对于 表示选择个数的第二维(j) 可以进行斜率凸优化。
    直接斜率凸优化即可,复杂度变为(O(nlogK'))。实现代码戳我

  • 相关阅读:
    HDU 1850 Being a Good Boy in Spring Festival
    UESTC 1080 空心矩阵
    HDU 2491 Priest John's Busiest Day
    UVALive 6181
    ZOJ 2674 Strange Limit
    UVA 12532 Interval Product
    UESTC 1237 质因子分解
    UESTC 1014 Shot
    xe5 android listbox的 TMetropolisUIListBoxItem
    xe5 android tts(Text To Speech)
  • 原文地址:https://www.cnblogs.com/GuessYCB/p/9051438.html
Copyright © 2011-2022 走看看