美丽的人 - 动态编程

时间:2014-05-23 08:43:08

标签: c++ algorithm dynamic-programming

我正试图在http://acm.sgu.ru/problem.php?contest=0&problem=199解决美丽人问题,但我在某个测试用例中得到错误答案。

  

一个城市最负盛名的体育俱乐部有N名成员。   每个成员都很强大而且漂亮。更确切地说,我   该俱乐部的成员(成员在他们进入时编号   俱乐部)有力量Si和美女Bi。因为这是非常的   享有声望的俱乐部,其成员非常富裕   非凡的人,所以他们经常非常讨厌对方。   严格来说,俱乐部的第一名成员X先生讨厌第j名成员   俱乐部Y先生,如果Si≤Sj和Bi≥Bj,或者如果Si≥Sj和Bi≤Bj(如果   X先生的两个属性都大于相应的属性   Y先生,另一方面,他甚至没有注意到他,如果他的两个人   物业较少,他非常尊重Y先生。)

     

为了庆祝新的2003年,俱乐部的管理是   计划组织一个聚会。然而他们害怕如果两个   之后,彼此仇恨的人会同时参加聚会   喝一两杯他们就会开始打架。所以没有两个人讨厌   应该邀请彼此。另一方面,保持俱乐部   presti≥在适当的水平,管理层想要邀请为   很多人尽可能。

     

是唯一一个不怕触摸的政府   一台计算机,你要写一个程序,找出谁   邀请参加聚会。

     

输入

     

输入文件的第一行包含整数N - 数字   俱乐部成员。 (2≤N≤100,000)。接下来N行包含两行   每个数字 - Si和Bi分别为(1≤Si,Bi≤10^ 9)。

     

输出

     

在输出文件的第一行打印最大数量   可以邀请参加聚会的人。在第二行输出N.   整数 - 以任意顺序邀请的成员数量。如果   存在几种解决方案,输出任何一种解决方案。

Sample test(s)

Input


4
1 1
1 2
2 1
2 2

Output


2
1 4 

基本上我的方法是:

  1. 首先按照Beauty []
  2. 对数组Strength []进行排序
  3. 获取存储max lis直到我
  4. 的数组D [i]
  5. Optiomal solution = D(i) = { 1 + Max ( D(j) ) }其中j < iD[i] = max{ D[j] +1 } j < iStrength[j] < Strength[i]以及Beauty[j] < Beauty[i],如果没有这样的j则{ {1}}
  6. 我的方法中有什么遗漏?

    我的解决方案:

    D(i) = 1

2 个答案:

答案 0 :(得分:2)

因此有一种有趣的方式可以几何思考这个问题。想象一下,在轴上绘制一个带有S,B的图形,并为每个人设置一个x。 (删除任何重复的点,即如果s = s,b = b,你可以删除其中一个)。

然后,对于每个点/人,只有矩形中低点和左边的点才是可行的选择。所以我可以与每个人联系一个代表尊重他们的人数的数字。拨打这个号码C.

这为a *搜索提供了一个可接受的启发式算法。从右上角的根节点开始,我的“最佳”移动通常是具有最高C编号的移动,因为它保留了最多的选项供以后使用。此外,一旦我在树的基部找到了一个根,我只需要选择其他分支,如果它们的C数高于实际的人数,那么大部分树将很快终止。

我怀疑这种类型的搜索平均是最优的,但根据点的分布情况,它可能会有慢速边缘情况。

enter image description here

这说明了它是如何工作的,你从一些根节点开始,并在第一次运行时它转到最高的C号,当它终止时,它重新计数以提供“答案”,因此它只是必须检查C号严格大于当前最佳答案的分支。在这种情况下,没有其他分支。

很容易直观地看出,如果点在S和B中均匀分布,这可能会非常快,但如果它们围绕y = x强烈聚类可能会非常慢,因为那样你就不会非常快地排除分支典型。

答案 1 :(得分:2)

您的解决方案输出的人员索引不正确。当您对输入进行排序时,它们的顺序已更改。只需将其他索引存储到您的结构中并使用它。
但是,你的代码会得到TLE,因为O(N ^ 2)。您需要O(NlogN)解决方案,这是LIS的经典解决方案。