【问题标题】:How to find the minimum number of tiles needed to cover holes in a roof如何找到覆盖屋顶孔所需的最少瓷砖数量
【发布时间】:2016-08-13 14:47:17
【问题描述】:

我刚刚学习动态编程,偶然发现了一个我不知道如何用 Python 表述的问题:

给定一个长度为 55 的二进制数组 H1 表示屋顶上有一个洞,0 表示没有洞。 您可以使用的尾部长度为 1、13 或 55,每个尾部的部署成本分别为 3、13 和 50。 对于给定的孔数组H,返回覆盖所有孔的最小成本。

根据我所学到的,第一步是找到基本案例,并通过归纳推理。 所以,这里有一些我很容易找到的基本案例:

  • 13 号瓷砖比 5 块 1 号瓷砖更方便(成本:13 比 15 或更多)
  • 55 号瓷砖比 4 块 13 号瓷砖更方便(成本:50 对 52 或更多)

最初我认为第一点意味着如果在 13 个连续空间中有 5 个或更多孔,我应该始终选择 13 块。但是我认为这取决于以下漏洞。

如果你在问题中加入 1-tiles,第二点就更成问题了。例如,考虑在[0, 15, 29, 44] 位置有 4 个单孔,最好使用 4 个 1-tile(1 x 55-tile 成本 50,4 x 13-tiles = 52)。

所以看起来我必须评估阵列中所有可能的切片组合的孔的“间距”是多少。

我怎样才能把上面的代码写成(甚至是伪)代码?

【问题讨论】:

  • 你用python开始了一些东西吗?
  • 这听起来比 NP-complete 的 Knapsack_problem 还要复杂...
  • 这不是和stack的Computer Science关系更大吗? #just_asking
  • 你可以重叠瓷砖吗?
  • @Jean-FrançoisFabre,不是真的,除了试图在没有真正方向的情况下操纵输入。

标签: python algorithm dynamic-programming


【解决方案1】:

假设 cost[i] - 覆盖屋顶的前 i 个元素的最佳成本。 显然 cost[0] = 0(我们不需要任何钱来覆盖 0 个图块)。

让我们将状态描述为(位置,成本)。

从状态 (i,cost[i]) 我们可以得到 4 种不同的潜在状态:

  • (i + 1, cost[i] + 3)(当我们使用长度为 1 且成本为 3 的图块时)
  • (i + 13, cost[i] + 13) (tile length = 13, cost 也是 13)
  • (i + 55, cost[i] + 50) (tile length = 55, cost is 50)
  • (i + 1, cost[i])(我们忽略当前位置,这里不使用任何图块)

一旦我们使用上述规则之一改变状态,我们应该考虑:

  • 位置应该是
  • 如果我们以相同或更大的成本定位 i,我们不想继续(基本上动态规划在这里发挥作用,如果我们以相同或更差的结果处理子问题,我们不想继续)。
  • 如果这个 tile 有洞,我们就不能跳过这个 tile(我们的第 4 个状态转换)。

一旦我们运行所有这些状态转换,答案将是成本[总长度 (55)]

【讨论】:

  • 我已经仔细考虑了你的答案,但我不确定我是否完全掌握了它。在我看来,它可能会找到一个潜在的次优解决方案:当你写“如果这个瓦片有洞,我们不能跳过瓦片(我们的第四个状态转换)”,这是否意味着算法将总是选择 1 -long tile 而不是 13-long tile,因为成本总是更小(3 vs 13)?我错过了什么吗?
  • Jir,这里是代码示例,它可能会让你的事情变得更容易dotnetfiddle.net/lmSHWf我不熟悉 Python,希望 C# 能很好地为你工作。您可以直接在浏览器中使用它。
  • 现在很清楚了,谢谢!现在我明白你的意思了。
猜你喜欢
  • 1970-01-01
  • 2012-04-21
  • 2019-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-20
相关资源
最近更新 更多