我在 Google Code Jam 中阅读了这个优化问题。(比赛已经结束了,可以聊聊了。)
Armin 正在玩由 Hemisphere Games 开发的基于物理的益智游戏 Osmos。在这个游戏中,他扮演一个“微粒”,四处移动并吸收更小的微粒。
英文中的“mote”是一个小颗粒。在这个游戏中,它是一个吸收(或被吸收)其他东西的东西!本题中的游戏与 Osmos 有类似的想法,但并不假设你已经玩过这款游戏。
当 Armin 的尘埃吸收了一个较小的尘埃时,他的尘埃会随着较小尘埃的大小而变大。现在它更大了,它可能能够吸收更多的微粒。例如:假设 Armin 的 mote 大小为 10,还有其他大小为 9、13 和 19 的 mote。一开始,Armin 的 mote 只能吸收大小为 9 的 mote。当它吸收时,它的大小为 19。然后它只能吸收大小为 13 的微粒。当它吸收时,它将具有大小 32。现在阿明的微粒可以吸收最后一个微粒。
请注意,Armin 的微粒可以吸收另一个微粒当且仅当另一个微粒更小。如果另一个尘埃与他的大小相同,他的尘埃就无法吸收它。
您负责为 Armin 创建微尘以吸收的程序。该程序已经创建了一些大小不一的mote,并创建了Armin 的mote。不幸的是,考虑到他的微尘的大小和其他微尘的列表,Armin 的微尘可能无法将它们全部吸收。
你想解决这个问题。您可以按任意顺序、任意次数执行两种操作:您可以将任意正整数大小的微尘添加到游戏中,或者您可以移除任何一个现有微尘。为了使 Armin 的微粒能够吸收所有其他微粒,您可以执行这些操作的最少次数是多少?
例如,假设 Armin 的 mote 大小为 10,而其他 mote 的大小为 [9, 20, 25, 100]。此游戏目前无法解决,但通过添加大小为 3 的微尘并移除大小为 100 的微尘,您只需 2 次操作即可解决此问题。这里的答案是2。
如何解决?(请用散文解释,而不是神秘代码)
我认为“给定一个可行的解决方案,删除一个尺寸为 x 并添加一个更大的尺寸为 y,有一个更好的(至少同样好)可行的解决方案,其中所有添加的节点都小于所有删除的节点”(而不是删除mote size x,在较大的mote size y之后吃掉它)
这提出了一种快速算法。将微粒从小到大排序。吃。如果卡住,记录“删除其余部分”作为潜在的解决方案。添加尘埃大小player - 1
,直到大到可以吃掉我们粘在上面的尘埃。重复。记录最终的“仅添加”解决方案。从记录的那些中选择最优解。
我在 Python 中实现了这个算法。我相当确定我的代码正确地实现了我的算法。我猜我的算法错了?