【发布时间】: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