最近【清华集训】里怒现三维最小乘积生成树,我太弱了~~(暴%镇中lyc神犇)。
由于本蒟蒻不懂三维计算几何,所以先来玩一下二维的。
现在没有时间去找例题做,先把思路放在这,到时候再补。
裸题描述:
给你n个二元组[x,y],要你从中选k个二元组,使得 ∑x∗∑y 最小。
我们把每一种选法得出的
∑x
和
∑y
看作二维平面中的点(
∑x
,
∑y
)。
使
∑x∗∑y
最小,就是使这个点作垂线到坐标轴所围成的长方形的面积最小,如图:
结论:
把所有的点列出来,建一个下凸壳,下凸壳的左下方没有其它点,最优的点只会这个下凸壳上。
这个挺显然的,随便画个图搞搞就知道了。
做法:
按所有的点 点乘上(0, 1)的点积排个序,取前k个点,合并起来,就是这个下凸壳的右端点。
再按所有的点 点乘上(1, 0)的点积排序,取前k个点,合并起来,就是这个下凸壳的左端点。
连接这两个点,做一个向量,这两个点构成的直线往这个向量的法向量的方向的最远的点就是凸壳需要找的下一个点,为了找到它,我们按所有的点 点乘上这个法向量的点积排序,取前k个点,合并起来就是下一个点。
流程图如下(本人画图水平太烂,忽略以下图中背后的坐标系,只看线):
1.
2.
3.
这样子做的话,理论复杂度是O(凸壳上的点数×n×log n),但是,据说凸壳上的点特别少,所以,我还是不会,只需要知道一般不会T就好了,到时我再实测吧。
待填坑……