【问题标题】:An algorithm for solving Google Code Jam tutorial problem C一种解决Google Code Jam教程问题C的算法
【发布时间】:2011-01-14 17:01:39
【问题描述】:

我想了解解决Google Code Jam, Tutorial, Problem C 的算法。到目前为止,我写了my own basic implementation 来解决这个小问题。我发现它无法处理大问题(复杂度 O(min(n, 2*k)! 这是 30! 在更大的数据集中)。

我找到了这个solution page,但解决方案当然没有记录(上下文有时间限制)。我看到至少有一个解决方案使用了Union Find data structure,但我不明白它是如何应用在这里的。

有谁知道有解决这些问题的算法的页面,而不仅仅是代码?

【问题讨论】:

    标签: algorithm graph


    【解决方案1】:

    不确定是否有更好的方法来处理这个几乎重复的 GCJ - Hamiltonian Cycles,但这是我的答案:

    基于 O(2k) 的解决方案使用 inclusion-exclusion principle。鉴于存在 k 个禁止边,则这些边有 2k 个子集边,包括集合本身和空集。例如,如果有 3 个禁止边:{A, B, C},则将有 23=8 个子集:{}、{A}、{B}、{C}、{ A,B}, {A,C}, {B,C}, {A,B,C}。

    对于每个子集,您计算至少包括该子集中所有边的循环数。如果包含边 s 的循环数是 f(s)S是所有禁止边的集合,则根据包含-排除原则,没有任何禁止边的循环数为:

     sum, for each subset s of S: f(s) * (-1)^|s|
    

    在哪里|s|是 s 中的元素数。换句话说,任何边的循环数的总和减去至少有 1 个禁止边的循环数加上至少有 2 个禁止边的数字,. ..

    计算 f(s) 并非易事——至少我没有找到简单的方法。在继续阅读之前,您可能会停下来思考一下。

    要计算 f(s),从不涉及任何 s 的节点的排列数开始强>节点。如果有 m 个这样的节点,那么就有 m!排列,如你所知。调用排列数c

    现在检查 s 中的边缘是否有链。如果有任何不可能的组合,例如一个节点涉及3条边或s内的一个子循环,则f(s) 为 0。

    否则,对于每个链,将 m 加 1 并将 c 乘以 2m。 (有 m 个位置可以将链放入现有排列中,因子 2 是因为链可以向前或向后。)最后,f(s)c/(2m)。最后一个除法将排列转换为循环。

    【讨论】:

      【解决方案2】:

      对输入数据施加的重要限制是禁止边数 k

      您可以通过包含和排除继续:

      • 计算所有循环的次数((n-1)!),
      • 对于每个禁止边 e,减去包含它的循环数((n-2)!/2,除非 n 非常小),
      • 对于每对禁止边 e,f,添加包含它们的循环数(这将取决于 e 和 f 是否接触),
      • 对于每个三元...,减去...,
      • 等。

      由于 F(所有禁止边的集合)只有 2^k

      google code jam问题Endless Knightanalysis使用了类似的思路。

      【讨论】:

        【解决方案3】:

        哈密顿循环问题旅行商问题的特例(如果两个城市相邻,则将它们之间的距离设为有限常数,否则设为无穷大。)

        这些是 NP 完全问题,简单来说意味着 没有已知的快速解决方案

        要解决有关 Google Code Jam 的问题,您应该了解算法分析和设计,尽管它们可以在指数时间内解决,而且不用担心 Google 非常了解。 ;)

        以下来源应该足以让您入门:

        1. MIT 讲座视频:“算法简介”

        2. TopCoder Tutorials

        3. http://dustycodes.wordpress.com

        4. 书籍:算法简介 [Cormen、Leiserson、Rivest 和 Stein]

        5. 算法设计手册 [Steven S. Skiena]

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-08-10
          • 1970-01-01
          • 1970-01-01
          • 2013-10-09
          • 2020-07-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多