【问题标题】:Dynamic Programming - Primitive Calculator Python [duplicate]动态编程 - 原始计算器 Python [重复]
【发布时间】:2016-06-01 06:41:42
【问题描述】:

本作业旨在对只能加 1、乘以 2 和乘以 3 的原始计算器实现动态编程方法。因此,输入 n 确定达到 n 的最小操作数。我已经实现了一个非常幼稚的 dp 或我认为是 dp 方法。它不工作。我没有人要问了。对于 n = 5 的输入,以下输出为: ([0, 1, 2, 2, 3, 4], [1, 1, 2, 3, 4, 5]) 而对于列表编号 = [1, 2, 4, 5] 或 [1, 3, 4, 5]。一些帮助将不胜感激。

def DPmin_operations(n):

numbers = []
minNumOperations = [0]*(n+1)
numOps = 0
numbers.append(1)

for k in range(1,n+1):
    minNumOperations[k] = 10000

    # for *3 operator
    if k % 3 == 0:
        numOps = minNumOperations[k//3] + 1
        if numOps < minNumOperations[k]:
            minNumOperations[k] = numOps
            numbers.append(k)
    # for *2 operator
    elif k % 2 == 0:
        numOps = minNumOperations[k//2] + 1
        if numOps < minNumOperations[k]:
            minNumOperations[k] = numOps
            numbers.append(k)
    # for + 1 operator 
    elif k >= 1:
        numOps = minNumOperations[k - 1] + 1
        if numOps < minNumOperations[k]:
            minNumOperations[k] = numOps
            numbers.append(k)

return (minNumOperations, numbers)

【问题讨论】:

  • 我会考虑在您的代码中添加一些 cmets,以便更容易解释您要执行的操作。或者至少解释一下你为什么要这样创建代码的想法。可能会让你更容易看到你想如何解决它。

标签: python dynamic-programming


【解决方案1】:

请注意,elif 块实际上应该是 if 块。目前,您正在使用总是试图除以 3 的贪心算法;如果失败,则尝试除以 2;如果失败,则减 1。有可能一个数字可以被 6 整除,因此所有三个选项都是可能的,但除以 2 比除以 3 更佳。

至于获取您的数字列表,请在最后进行。存储所有可能的父母,然后从你的目标向后工作,看看你是如何到达那里的。

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])

【讨论】:

  • 非常感谢您的回答。我很难理解 DP。
  • 这就像一个魅力,但我仍然很难理解它是如何工作的。很折腾。
猜你喜欢
  • 2016-08-29
  • 1970-01-01
  • 1970-01-01
  • 2016-08-24
  • 2021-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多