Convert 1 into X in min steps by multiplying with 2 or 3 or by adding 1

Given an integer X, the task is to convert 1 into X by using the below-given operations: 

  • Multiply the number by 2.
  • Multiply the number by 3.
  • Add 1 to the number.

The task is to print the minimum number of operations needed to convert 1 into X using these three operations and also print the sequence of operations performed.

Examples:

Input: X = 5
Output:

1 3 4 5 
Explanation: 
Before any operation, X = 1
1st Operation: Multiply the number 1 by 3, hence X = 3.
2nd Operation: Add 1 to the number 3, hence X = 4.
3rd Operation: Add 1 to the number 4, hence X = 5. 
Therefore, minimum 3 operations are required and the sequence is 1 3 4 5. 

Input: X = 20
Output:

1 3 9 10 20 
Explanation: 
Before any operation, X = 1
1st Operation: Multiply the number 1 by 3, hence X = 3.
2nd Operation: Multiply the number 3 by 3, hence X = 9.
3rd Operation: Add 1 to the number 9, hence X = 10. 
4th Operation: Multiply the number 10 by 2, hence X = 20.
Therefore, minimum 4 operations are required and the sequence is 1 3 9 10 20 .



 

Naive Approach: The simplest approach is to find all possible sequences of operations to convert 1 into X and return the one with the minimum number of operations.
Time Complexity: O(3N)
Auxiliary Space: O(1)

Efficient Approach: To optimize the above naive approach the idea is to use Dynamic Programming to find the minimum number of operations and then backtrack to find the required sequence of operations. Below are the steps:

  1. Initialize the dp[] to store the minimum number of operations for every index i to reach 1 to i.
  2. Now dp[X] store the minimum number of operations required to make X from 1. We will fill the dp[] array in the Bottom-Up Approach. For the any value X we can reduce in one of the below ways:
    1. If X is divisible by 2, then divide it by 2 and count this operation.
    2. If X is divisible by 3, then divide it by 3 and count this operation.
    3. Else subtract 1 from X.
  3. From the above steps, the recurrence relation formed is given by:
dp[X] = min(dp[X/2] + 1,  // If X is divisible by 2
            dp[X/3] + 1,  // If X is divisible by 3
            dp[X-1] + 1)

Base Condition:
dp[1] = 0  // As no operation required when X = 1
  1. After the dp[] array is created, backtrack using the values stored in the array and store the sequence in the list.
  2. Print the minimum operations and the sequence stored in the list.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach 
#include<bits/stdc++.h>
using namespace std;
  
// Function to print the Minimum number 
// of operations required to convert 1 
// into X by using three given operations
void printMinOperations(int N)
{
      
    // Initialize a DP array to store 
    //min operations for sub-problems 
    int dp[N + 1];
    for(int i = 0; i < N + 1; i++)
        dp[i] = N;
          
    // Base Condition: 
    // No operation required 
    // when N is 1 
    dp[1] = 0;
      
    for(int i = 2; i < N + 1; i++)
    {
          
        // Multiply the number by 2
        if (i % 2 == 0 && dp[i] > dp[i / 2] + 1)
            dp[i] = dp[i / 2] + 1;
              
        // Multiply the number by 3 
        if (i % 3 == 0 && dp[i] > dp[i / 3] + 1) 
            dp[i] = dp[i / 3] + 1;
              
        // Add 1 to the number.
        if (dp[i] > dp[i - 1] + 1) 
            dp[i] = dp[i - 1] + 1;
    }
      
    // Print the minimum operations 
    cout << dp[N] << endl;
      
    // Initialize a list to store 
    // the sequence
    vector<int>seq;
      
    // Backtrack to find the sequence 
    while (N > 1)
    {
        seq.push_back(N); 
          
        // If add by 1 
        if(dp[N - 1] == dp[N] - 1) 
            N = N - 1;
              
        // If multiply by 2 
        else if (N % 2 == 0 &&
              dp[N / 2] == dp[N] - 1) 
            N = N / 2;
              
        // If multiply by 3 
        else
            N = N / 3;
    }
    seq.push_back(1);
      
    // Print the sequence of operation 
    for(int i = seq.size() - 1; i >= 0; i--)
        cout << seq[i] << " ";
          
    cout << endl;
}
  
// Driver code
int main()
{
      
    // Given number X
    int X = 96234;
          
    // Function call
    printMinOperations(X);
}
  
// This code is contributed by Stream_Cipher

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for the above approach 
import java.util.*; 
  
class GFG{
  
// Function to print the Minimum number 
// of operations required to convert 1 
// into X by using three given operations
static void printMinOperations(int N)
{
      
    // Initialize a DP array to store 
    //min operations for sub-problems 
    int dp[] = new int[N + 1];
    for(int i = 0; i < N + 1; i++)
        dp[i] = N;
          
    // Base Condition: 
    // No operation required 
    // when N is 1 
    dp[1] = 0;
      
    for(int i = 2; i < N + 1; i++)
    {
          
        // Multiply the number by 2
        if (i % 2 == 0 && dp[i] > dp[i / 2] + 1)
                dp[i] = dp[i / 2] + 1;
                  
        // Multiply the number by 3 
        if (i % 3 == 0 && dp[i] > dp[i / 3] + 1
            dp[i] = dp[i / 3] + 1;
              
        // Add 1 to the number.
        if (dp[i] > dp[i - 1] + 1
            dp[i] = dp[i - 1] + 1;
    }
      
    // Print the minimum operations 
    System.out.println(dp[N]);
      
    // Initialize a list to store 
    // the sequence
    Vector<Integer> seq = new Vector<Integer>();
      
    // Backtrack to find the sequence 
    while (N > 1)
    {
        seq.add(N);
          
        // If add by 1 
        if(dp[N - 1] == dp[N] - 1
            N = N - 1;
              
        // If multiply by 2 
        else if (N % 2 == 0 && 
              dp[N / 2] == dp[N] - 1
            N = N / 2;
              
        // If multiply by 3 
        else
            N = N / 3;
          
    }
    seq.add(1);
      
    // Print the sequence of operation 
    for(int i = seq.size() - 1; i >= 0; i--)
        System.out.print(seq.get(i) + " ");
}
  
// Driver code
public static void main(String args[]) 
      
    // Given number X
    int X = 96234;
      
    // Function call
    printMinOperations(X);
}
}
  
// This code is contributed by Stream_Cipher

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program for the above approach 
  
# Function to print the Minimum number 
# of operations required to convert 1 
# into X by using three given operations 
  
  
def printMinOperations(N): 
  
    # Initialize a DP array to store 
    # min operations for sub-problems 
    dp = [N]*(N + 1
  
    # Base Condition: 
    # No operation required 
    # when N is 1 
    dp[1] = 0
  
    for i in range(2, N + 1): 
  
        # Multiply the number by 2 
        if (i % 2 == 0 and dp[i] > dp[i//2]+1): 
            dp[i] = dp[i//2]+1
  
        # Multiply the number by 3 
        if (i % 3 == 0 and dp[i] > dp[i//3]+1): 
            dp[i] = dp[i//3]+1
  
        # Add 1 to the number. 
        if (dp[i] > dp[i-1]+1): 
            dp[i] = dp[i-1] + 1
  
    # Print the minimum operations 
    print(dp[N], end ="\n"
  
    # Initialize a list to store 
    # the sequence 
    seq = [] 
  
    # Backtrack to find the sequence 
    while (N > 1): 
        seq.append(N) 
  
        # If add by 1 
        if dp[N-1] == dp[N] - 1
            N = N-1
  
        # If multiply by 2 
        elif N % 2 == 0 and dp[N//2] == dp[N] - 1
            N = N//2
  
        # If multiply by 3 
        else
            N = N//3
    seq.append(1
  
    # Print the sequence of operation 
    for i in reversed(seq): 
        print(i, end =" "
  
  
# Driver Code 
  
# Given number X 
X = 96234
  
# Function Call 
printMinOperations(X) 

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program for the above approach 
using System; 
using System.Collections.Generic;
  
class GFG{
      
// Function to print the Minimum number 
// of operations required to convert 1 
// into X by using three given operations
static void printMinOperations(int N)
{
      
    // Initialize a DP array to store 
    //min operations for sub-problems 
    int []dp = new int[N + 1];
    for(int i = 0; i < N + 1; i++)
        dp[i] = N;
          
    // Base Condition: 
    // No operation required 
    // when N is 1 
    dp[1] = 0;
      
    for(int i = 2; i < N + 1; i++)
    {
          
        // Multiply the number by 2
        if (i % 2 == 0 && dp[i] > dp[i / 2] + 1)
                dp[i] = dp[i / 2] + 1;
                  
        // Multiply the number by 3 
        if (i % 3 == 0 && dp[i] > dp[i / 3] + 1) 
            dp[i] = dp[i / 3] + 1;
              
        // Add 1 to the number.
        if (dp[i] > dp[i - 1] + 1) 
            dp[i] = dp[i - 1] + 1;
    }
      
    // Print the minimum operations 
    Console.WriteLine(dp[N]);
      
    // Initialize a list to store 
    // the sequence
    List<int> seq = new List<int>();
      
    // Backtrack to find the sequence 
    while (N > 1)
    {
        seq.Add(N); 
          
        // If add by 1 
        if(dp[N - 1] == dp[N] - 1) 
            N = N - 1;
              
        // If multiply by 2 
        else if (N % 2 == 0 && 
              dp[N / 2] == dp[N] - 1) 
            N = N / 2;
              
        // If multiply by 3 
        else
            N = N / 3;
    }
    seq.Add(1);
    seq.Reverse();
      
    // Print the sequence of operation 
    foreach(var i in seq)
    {
        Console.Write(i + " ");
    }
}
  
// Driver code
public static void Main() 
      
    // Given number X
    int X = 96234;
      
    // Function call
    printMinOperations(X);
}
}
  
// This code is contributed by Stream_Cipher

chevron_right


Output:

14
1 3 9 10 11 33 99 297 891 2673 8019 16038 16039 48117 96234 

Time Complexity: O(N)
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Recommended Posts:


Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : Stream_Cipher