如何更改此贪心算法以预测最高总分?

Posted

技术标签:

【中文标题】如何更改此贪心算法以预测最高总分?【英文标题】:How do I change this greedy algorithm to predict the most overall score? 【发布时间】:2022-01-11 23:20:18 【问题描述】:

大家好,这是我在这里的第一篇文章。

所以今天在我的大学课上,我们的教授给了我们一个任务来写一个算法:

编写一个函数,返回在棋盘游戏中获得最高分所需的步数:

游戏规则:

您掷骰子并相应移动(1-6 步)。 棋盘上的棋子数量可以在 2 - 99 999 之间。 当您踩到一块瓷砖时,您会获得或失去积分(每个瓷砖上的积分从 -99 999 到 99 999 不等)。 如果你在棋盘的尽头并且你的掷骰子让你脱离了它的边界,你就不会移动。

我的方法

这是一种贪心算法:

如果每一步大于或等于 0,则计数, 如果是负数,请检查接下来的 6 个图块并移至得分最高的图块,以减少分数。

在我想象了这个例子之后,我意识到我的方法是错误的:

想象一个包含 1, -40, -40, -40, -40, -1, -38, -40, -40, -40, -40, -40, 1 的数组

我的贪心算法从 1 开始,看到四个 -40,一个 -38 和一个 -1。它选择 -1 是因为它是最好的选择,但现在我们将得到以下结果:1 + (-1) + (-38) + 1 = -37,但是如果我们选择 -38 而不是 -1,我们最终会是:1 + (-38) + 1 = -36。

这只是问题的一个简单示例,我想我必须检查每条可能的路径,因为贪心算法不会检查那里的最佳路径,只检查最适用于某些特定的路径时刻。

我想知道这里是否可以选择包含所有可能性的图,但是如果我们只有一个负数数组,那么我们最终会得到一个最大大小约为 (99999^6?) 的图,这会导致占用过多的内存。

我是新手,我的想法已经用完了。谁能指出我正确的方向?

【问题讨论】:

是否指定必须使用贪心算法? 正如您所确定的,贪婪的方法并不总是给出正确的答案。但是,基于递归/动态编程的方法可能会。给定您的分数数组A,将best(A, i) 定义为您可以从索引i 开始获得的最佳分数。您需要解决best(A, 0),并且因为可以执行 1-6 步,best(A, 0) = A[0] + max(best(A, k))1 <= k <= 5。从这里,您可以为A 的任意索引定义一般重复。 更新了我的答案以包含一个贪婪的解决方案。 也许会在我们迭代时保留数组中每个项目的步数和最佳分数的历史记录。因此,对于数组中的每个新项目,我们通过将步骤添加到最后六个空格中的任何一个来找到最佳分数。每个数组大小最多使用一个 int 和一个 long,但如果您真的想尽量减少内存使用,则可以删除任何超过六个空格的结果。 不,我不需要使用贪心算法,这只是我解决这个问题的方法。 @亚历克斯 【参考方案1】:

哦,等等!在这里使用最大堆可以实现贪婪。

想法:

最大堆是一种数据结构,它在结构的顶部保持最大元素。如果我们在最大堆中保留掷骰子后可能出现的 6 个值,我们可以得到最大可能掷骰子的值。

让我们考虑一下您的示例数组 1, -40, -40, -40, -40, -1, -38, -40, -40, -40, -40, -40, 1。

推送骰子可以在最大堆中滚动的前六个值。因此,最大堆包含元素 , , , , , (不是最大堆顺序)。

这里<top of the max heap>.value = 1 和<top of the max heap>.index = 0。

现在,max_score = 1。

在弹出最大堆并从数组中添加下一个元素后,最大堆将包含以下元素 , , , , , (不是最大堆顺序)。

同样,您可以使用以下算法计算输入数组中的剩余元素。

算法:

max_score, curr_index, steps = 0
Push input_array[0..max(5, size_of_input_array - 1)] values in a max heap in the form <value, index in the array>
i = 6

while(max heap is not empty):
    while(max heap is not empty and <top of the max heap>.index < curr_index):
        pop the max heap
    if(max heap is not empty):
        max_score += <top of the max heap>.value
        curr_index = <top of the max heap>.index
        steps++
        pop the max heap
    if(i < size_of_input_array):
        push the <input_array[i], i> into the max heap
        i++
return max_score, steps

Time complexity: O(size_of_input_array * log(6)) => O(size_of_input_array)
Space complexity: O(6) => Constant

没有给出完整的工作代码,因为这是你的任务,但上述算法不少于代码。

您也可以尝试使用Depth First Search、Dynamic Programming。但上述贪心解法是渐近最有效的方法。

希望对您有所帮助。我喜欢解决它。谢谢!

【讨论】:

没关系,我发现这个答案很有帮助:) 一段时间后访问这个问题 - 我可以清楚地看到它有所改善。赞成。将删除不再适用的我的 cmets

以上是关于如何更改此贪心算法以预测最高总分?的主要内容,如果未能解决你的问题,请参考以下文章

算法学习——贪心算法之删数字(求最大值)

增强学习贪心算法与Softmax算法

具有最高薪水问题的贪心算法?

算法学习——贪心算法之可拆背包

贪心算法的简单理解

十:贪心算法-背包问题