给定一个 N人的课程(这由数组int [] a)表示,其中每个人与所有其他人一起玩游戏。每场比赛只涉及2名球员。所以N人将会有 NC2 游戏。
所有游戏都有你的结果。你必须安排队列中的每个人,条件是 a [i]应该用[i-1] 赢得比赛。对于i的所有值都是如此。
我们不需要关心[i]和[i-2]之间的结果。 a [i]可能会以[i-2] 赢或输。
我的方法(我用回溯来解决这个问题):
以上解决方案将使用递归方法尝试每条路径。有没有更好的算法?
答案 0 :(得分:3)
数学上你所拥有的是一种叫做锦标赛图的东西,你试图找到该锦标赛图中的汉密尔顿路径。虽然在任意图中找到汉密尔顿路径的问题是NP难的,但众所周知,每个锦标赛图必须有哈密顿路径,幸运的是它们并不难找到。
一种简单的方法是使用递归。如果图中只有一个节点,那么解决这个问题非常简单:只需在图表中列出一个人。否则,任意选择一些节点。将比赛分成次级锦标赛:击败那个人的所有人中的一个以及那个人输给的所有人中的一个。递归地在每个子锦标赛中获得哈密尔顿路径。然后,将哈密尔顿路径连接在一起,将你在第一步中挑出的人放在他们之间的适当位置。
这个算法有多高效?像quicksort一样,算法的效率取决于你如何将锦标赛分成更小的部分。假设当您选择一个人将比赛分成较小的部分时,您选择胜利数量尽可能接近n / 2的人。这将产生两个较小的比赛,大小约为n / 2。确定选择哪个人需要二次时间,因为你必须查看每个游戏的结果,以计算玩家有多少输赢。这给了我们以下的递归关系:
T(n)= 2T(n / 2)+ O(n 2 )
使用主定理,我们得出这个递归求解为O(n 2 ),这比你最初的想法要快得多。
希望这有帮助!
答案 1 :(得分:1)
这是一个提示:
假设我们已经为满足约束条件的第一批i-1人进行了排序。是否总能将人i插入此列表中?
考虑这些案例:无论是我击败所有第一批i-1人,还是没有人,或其中一些人,但不是所有人。在前2个案例中我可以插入哪个人? (到目前为止,可能有助于为列表中的每个i-1人分配1或0,指示该人是否击败了我。)在第三种情况下,我们可以在他们击败的任何人之间插入人i和任何击败他们的人。这样的一对总是存在吗?如果没有,是否有其他地方我们可以保证能够安全地插入人物?