wqs二分详解
废话
学这个算法的时候,深切的体会到,能找到一篇好的文章来学习是多么幸福啊……
正题
这是一个用来解决这样一类问题的算法:
有若干个物品,要求你选出 个,选的时候带有限制,要你求出最优的方案。
用的时候有一个大前提,就是,设 表示选 个物品的最优方案,那么将所有点 画出来,他们一定要组成一个凸包(上凸下凸皆可),所有点都在上面的那种,这样就有一个性质:斜率单调递增或递减。
这种题的特点是:如果不限制选的个数,很容易就能求出最优方案。
下面以上凸包(从左到右斜率递减)为例子。
现在,我们的目标就是,求出 。
做法是,二分一个斜率 ,然后找到斜率为k的切这个凸包的直线
切于哪一点。
可以发现,随着 的减小,这条直线切的点会越来越靠右,就像这样:(这图也不算太严谨,因为有些点没画,比如 之类……)
于是我们二分 直到这条直线切的点的横坐标是 ,那么这个点的纵坐标 就是答案了。
于是问题变成了:当二分出一个 时,怎么求被切的点是谁。
很有规律,你康康这个就懂了:被切点上的直线,是在最上面的,也就是说,这条直线在 轴上的截距最大。
设这个截距为 ,那么经过点 的斜率为 的直线在 轴上的截距就是 。
现在问题变成了,找到最大的 。
考虑一下 的意义,他等于 ,而 等于选 个物品时的最优解,那么 就相当于选的每个物品的价值都减 后的最优解。
由于我们现在要求的是最大的 ,也就是所有物品的价值都减 之后的最优解,根据上面的特点,在没有数量限制的情况下,最优解是很容易求的,于是就做完啦!
最后再讲讲 的调整,当此时的 求出来的最大的 的 小于 时,根据图像,很容易知道我们应该将斜率减小,也就是让 ,这样才能让切点右移,从而逼近点 。
大多题目在整数域内二分即可,有些特别的题可能需要将斜率二分到小数级别。
题表
可能还会更新的qwq