动态编程 - 原始计算器

时间:2017-12-18 04:15:45

标签: python algorithm dynamic-programming

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

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

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

我从后面跟踪部分有了解问题     “numbers = []     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])

1 个答案:

答案 0 :(得分:0)

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

1)min_operations[n-1]

2)if(n可被2整除)

         min_operations[n/2] 

3)if(n可被3整除)

         min_operations[n/3]

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

现在您知道达到1的最小操作数为零。所以现在开始计算从1到n的最小操作数。因为每当你计算任何数字时,你就会得到所有小于k的数字的答案。 k-1,k / 2(如果可分),k / 3(如果可分)。因此,你可以计算n,如果你将从1遍历到n,找到中间所有数字的答案。