我想用動態規劃解決以下問題。動態規劃 - 原始計算器
給出一個原始計算器,它可以用當前數字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'數組。你有所有需要理解的工具。你只需要花一點時間就可以使用它們。 –