Atcoder Regular Contest 092 A 的改编

原题地址

题目大意

给定平面上的 \(n\) 个点 \(p_1, \dots, p_n\) 。第 \(i\) 点的坐标为 \((x_i, y_i)\)\(x_i\) 各不相同,\(y_i\) 也各不相同。若两点 \(p_i\)\(p_j\) 满足 \(x_i < x_j\)\(y_i < y_j\) 则可配成一对。求这 \(n\) 个点之中最多可配成多少对。(注:每个点最多出现在一个点对中)

解法

\(y\) 坐标从大到小考虑。\(y\) 值最大的点,不妨记为 \((x_i, y_i)\), 与 \(x\) 坐标小于 \(x_i\)\(y\) 坐标小于 \(y_i\) 的点中 \(y\) 坐标最大的点配对。若此循环。

实现

怎么实现比较简洁呢?
不要总想着模拟,多想想要求的量是什么?什么东西是不必计算的?
想了一下,没挖掘出进一步的规律,所以 end up with 模拟,sigh。。

一个模拟算法:
\(n\) 个点按 \(x\) 坐标从小到大排序。用 std::map<int,int> 保存每个 \(y\) 坐标值(所属的点)在排序后的序列中位置。
用树状数组支持查询“前 \(i\)\(y\) 坐标值中的最大值”,用掉的点的 \(y\) 坐标替换为 \(-\infty\)

还是觉得这个做法太蠢了,一点都不优雅。


EDIT 1
这样改编貌似没啥新意。先考虑一维的情况(一维是平凡情形)就不难想到二维的解法。那么三维、四维怎么做呢?

posted @ 2018-03-20 22:07  Pat  阅读(161)  评论(1编辑  收藏  举报