斜率凸优化小结

斜率凸优化小结

前言

很久以前考了一道叫做"林克卡特树"的题目( 还记得被八省联考支配的恐惧吗?)
正解是用直线去切一个凸函数......
当时并不是很会。然而\(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):
1210540-20180517153935821-855962771.png

例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')\)。实现代码戳我

转载于:https://www.cnblogs.com/GuessYCB/p/9051438.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值