我正在尝试使用动态编程解决以下问题。
您将获得一个原始计算器,可以使用当前数字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])
答案 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,找到中间所有数字的答案。