【问题标题】:Dynamic Programming - Primitive Calculator动态规划 - 原始计算器
【发布时间】:2017-12-18 04:15:45
【问题描述】:

我正在尝试使用动态编程解决以下问题。

给你一个原始计算器,它可以对当前数字 x 执行以下三个操作:将 x 乘以 2、将 x 乘以 3 或将 x 加 1。你的目标是给定一个正整数 n,从数字 1 开始找到获得数字 n 所需的最小操作数。 输出应包含两部分 - 最小操作数,以及从 1 到 n 的序列。

我从这篇文章中找到了以下解决方案:Dynamic Programming - Primitive Calculator Python

我在理解回溯部分时遇到问题,从 “数字= [] k = n" 谁能解释一下它背后的逻辑?它像魔术一样工作......

代码如下:

def dp_min_ops(n):
    all_parents = [None] * (n + 1)
    all_min_ops = [0] + [None] * n

    for k in range(1, n + 1):
        curr_parent = k - 1
        curr_min_ops = all_min_ops[curr_parent] + 1

        if k % 3 == 0:
            parent = k // 3
            num_ops = all_min_ops[parent] + 1
            if num_ops < curr_min_ops:
                curr_parent, curr_min_ops = parent, num_ops

        if k % 2 == 0:
            parent = k // 2
            num_ops = all_min_ops[parent] + 1
            if num_ops < curr_min_ops:
                curr_parent, curr_min_ops = parent, num_ops

        all_parents[k], all_min_ops[k] = curr_parent, curr_min_ops

    numbers = []
    k = n
    while k > 0:
        numbers.append(k)
        k = all_parents[k]
    numbers.reverse()

    return all_min_ops, numbers

print(dp_min_ops(5))   # ([0, 1, 2, 2, 3, 4], [1, 3, 4, 5])
print(dp_min_ops(10))  # ([0, 1, 2, 2, 3, 4, 3, 4, 4, 3, 4], [1, 3, 9, 10])

【问题讨论】:

  • 了解那里发生的事情的方法是使用您的调试器。在numbers = [] 处放置一个断点,然后单步执行循环。每次查看numbers 的内容,并检查all_parents 数组。您拥有理解这一点所需的所有工具。你只需要花一点时间来使用它们。

标签: python algorithm dynamic-programming


【解决方案1】:

提示:找到达到数字 n 的最小操作。您将需要以下答案:

1)min_operations[n-1]

2) 如果 (n 能被 2 整除)

         min_operations[n/2] 

3) 如果 (n 能被 3 整除)

         min_operations[n/3]

现在,如果我们找到上述三个操作中的最小值,我们将通过将这三个操作中的最小值加一(如果有效)来达到 n 的最小操作数。

现在您知道达到 1 的最小操作数为零。所以现在开始计算从 1 到 n 的最小操作数。因为无论何时你要计算任何数字说 k,你总是会得到所有小于 k 的数字的答案,即。 k-1,k/2(如果可整除),k/3(如果可整除)。因此,如果您从 1 遍历到 n 以找到介于两者之间的所有数字的答案,则可以计算 n。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-24
    • 2016-08-29
    • 1970-01-01
    • 2012-03-26
    • 2013-11-27
    相关资源
    最近更新 更多