-2

I am trying to solve the following problem using dynamic programming.

You are given a primitive calculator that can perform the following three operations with the current number x: multiply x by 2, multiply x by 3, or add 1 to x. Your goal is given a positive integer n, find the minimum number of operations needed to obtain the number n starting from the number 1. The output should contain two parts - the number of minimum operations, and the sequence to get to n from 1.

I found the following solution from this post: Dynamic Programming - Primitive Calculator Python.

I am having problem understanding the back tracing part, starting from "numbers = [ ] k = n" Could anyone explain the logic behind it? It works like magic...

The code is as follows:

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])
Tian Park
  • 31
  • 4
  • The way to understand what's happening there is to use your debugger. Put a breakpoint at `numbers = []`, and then single-step your way through the loop. Look at the contents of `numbers` each time through, and examine the `all_parents` array. You have all the tools you need to understand this. You just have to spend a little time using them. – Jim Mischel Dec 18 '17 at 05:18

1 Answers1

0

Hint : To find the Minimum operations to reach a number n. You will need the following answers :

1) min_operations[n-1]

2) if ( n is divisible by 2)

         min_operations[n/2] 

3) if ( n is divisible by 3)

         min_operations[n/3]

Now if we find the minimum of these above three operations we will have minimum number of operations to reach n by adding one to the minimum of these three(if valid).

Now you know that minimum number of operations to reach 1 is zero. So now start calculating minimum number of operations from 1 to n. Since whenever you will calculate any number say k you will always have answer for all numbers less than k ie. k-1, k/2(if divisible), k/3(if divisible). Hence you could calculate for n if you would traverse from 1 to n finding answers for all numbers in between.

DSinghvi
  • 101
  • 3