【问题标题】:Modified egg dropping puzzle改良的鸡蛋掉落谜题
【发布时间】:2017-09-19 12:12:27
【问题描述】:

假设我有 m 个鸡蛋,并想知道 n 层 (n>=2) 建筑物中的哪些楼层可以安全掉落鸡蛋,以及会导致鸡蛋在着陆时破裂。

有几个假设:

  1. 在跌倒后幸存下来的鸡蛋会留在一楼,可以再次使用。我必须下到一楼去收集幸存的鸡蛋。
  2. 打碎的鸡蛋不能再使用。
  3. 跌倒对所有鸡蛋的影响都是一样的。
  4. 如果鸡蛋在掉落时破裂,那么如果从更高的窗户掉落,它也会破裂。
  5. 如果一个鸡蛋在坠落中幸存下来,那么它会在较短的坠落中幸存下来。
  6. 鸡蛋从最高楼层掉落时会破裂,而从一楼掉落时不会破裂。

我上楼梯难,下容易。

如何最大限度地缩短在较高楼层行驶的距离?

【问题讨论】:

  • 最小化什么?最坏情况、一般情况还是其他情况?
  • 在最坏的情况下最小化距离。
  • 您似乎可以通过以下方式参数化问题:完整掉落的鸡蛋数量、您持有的鸡蛋数量、您当前所在的楼层、您知道安全的最高楼层以及你知道的最低楼层是不安全的。然后使用 DP。
  • @PaulHankin 不需要 DP。这是纯粹的数学。
  • @user58697 我很想看到这个问题的纯数学解决方案。你在某处写过文章吗?

标签: algorithm dynamic-programming


【解决方案1】:

我在 Haskell 上找到了一般行驶距离的解决方案 here,然后在 Python 上重写了它并针对我的任务进行了修改。

from math import inf
from collections import namedtuple
from functools import lru_cache

Solution = namedtuple('Solution', ('moves', 'floors'))


@lru_cache(maxsize=None)
def solve(held, dropped, height, lo, hi):
    if hi == lo + 1:
        return Solution(0, [])
    solutions = list()
    if dropped:
        moves, floors = solve(held + dropped, 0, 1, lo, hi)
        solutions.append(Solution(moves, [1] + floors))
    if held:
        for _height in range(lo + 1, hi):
            breaks = solve(held - 1, dropped, _height, lo, _height)
            survives = solve(held - 1, dropped + 1, _height, _height, hi)
            worst = max((breaks, survives), key=lambda x: x.moves)
            solutions.append(
                Solution(
                    max(_height - height, 0) + worst.moves,
                    [_height] + worst.floors
                )
            )
    return min(solutions, key=lambda x: x.moves, default=Solution(inf, []))


print(solve(3, 0, 1, 1, 100))

【讨论】:

    猜你喜欢
    • 2017-02-28
    • 1970-01-01
    • 2016-01-01
    • 2017-05-29
    • 2020-05-18
    • 1970-01-01
    • 2017-03-08
    • 2011-07-08
    • 2010-11-25
    相关资源
    最近更新 更多