PointyWizardHats

作者:辜俊儒 钟知闲 徐明宽

关键字:二分图匹配 贪心

题目简述

给出两组圆锥形的帽子,每个帽子有一个高度 和半径

第一组中的帽子能放在第二组中的帽子上组合成一个新的帽子需满足:

  1. 两帽子的端点不相碰
  2. 第二组中的帽子不会被完全覆盖

最大化组合成的新帽子的个数。

每组中的帽子个数

解题思路

两帽子能配对,需满足

跑二分图最大匹配即可。

复杂度

另一种解法

对于该问题,有一种时间复杂度和代码实现难度上都优于二分图匹配的解法。

首先我们将所有的帽子按照 从大到小排序,然后按顺序将每个第二组的帽子 与第一组中 能匹配的帽子中 最大的一个 匹配。

为什么这样贪心是对的?

假设最优方案中第二组的第 个帽子 (已按 从大到小排序)没有按贪心策略匹配,那么将 改成和第一组中它能匹配的 最大的帽子 匹配,如果 被另一个第二组的帽子 匹配了,有两种情况:(1)原先 没有和任何第一组的匹配,则直接去掉 的匹配;(2)原先 匹配,则将 改成和 匹配,由于 ,且 ,这样的匹配一定是成立的。并且修改后的匹配数不会变少,因此按照该贪心策略可以得到最优解。

实现时,先将所有帽子按 从大到小排序,然后建立一个集合 和答案变量 (初始 ),按顺序考虑每个帽子 ,如果属于第一组,就加入 ,如果属于第二组,就从 中查找 小且 最大的 ,如果找到,就将其从 中删去并将 增加 ,没找到则 不变。最后 就是答案。

使用 C++STL 中的 multiset 可以高效完成集合插入及查找操作,复杂度 ,代码仅不到 ,十分简洁。

results matching ""

    No results matching ""