Open In App

Minimum number of operations required to reduce N to 0

Last Updated : 05 Apr, 2021
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an integer N, the task is to count the minimum steps required to reduce the value of N to 0 by performing the following two operations:

  • Consider integers A and B where N = A * B (A != 1 and B != 1), reduce N to min(A, B)
  • Decrease the value of N by 1

Examples :

Input: N = 3
Output: 3
Explanation:
Steps involved are 3 -> 2 -> 1 -> 0
Therefore, the minimum steps required is 3.
 
Input: N = 4
Output: 3
Explanation:
Steps involved are 4->2->1->0.
Therefore, the minimum steps required is 3.
 

Naive Approach: The idea is to use the concept of Dynamic Programming.  Follow the steps below to solve the problem:

  • The simple solution to this problem is to replace N with each possible value until it is not 0.
  • When N reaches 0, compare the count of moves with the minimum obtained so far to obtain the optimal answer.
  • Finally, print the minimum steps calculated.

Illustration:

N = 4,  

  • On applying the first rule, factors of 4  are [ 1, 2, 4 ]. 
    Therefore, all possible pairs (a, b) are (1 * 4), (2 * 2), (4 * 1).
    Only pair satisfying the condition (a!=1 and b!=1) is (2, 2) . Therefore, reduce 4 to 2
    Finally, reduce N to 0, in 3 steps(4 -> 2 -> 1 -> 0)
  • On applying the second rule, steps required is 4, (4 -> 3 -> 2 -> 1 -> 0). 
     
Recursive tree for N = 4 is
                  4
                /   \
               3     2(2*2)
               |      |
               2      1
               |      |
               1      0
               |
               0
  • Therefore, minimum steps required to reduce N to 0 is 3.

Therefore, the relation is:

f(N) = 1 + min( f(N-1), min(f(x)) ), where N % x == 0 and x is in range [2, K] where K = sqrt(N)

Below is the implementation of the above approach:

C++
// C++ Program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;

// Function to count the minimum
// steps required to reduce n
int downToZero(int n)
{
    // Base case
    if (n <= 3)
        return n;

    // Allocate memory for storing
    // intermediate results
    vector<int> dp(n + 1, -1);

    // Store base values
    dp[0] = 0;
    dp[1] = 1;
    dp[2] = 2;
    dp[3] = 3;

    // Stores square root
    // of each number
    int sqr;
    for (int i = 4; i <= n; i++) {

        // Compute square root
        sqr = sqrt(i);

        int best = INT_MAX;

        // Use rule 1 to find optimized
        // answer
        while (sqr > 1) {

            // Check if it perfectly divides n
            if (i % sqr == 0) {
                best = min(best, 1 + dp[sqr]);
            }

            sqr--;
        }

        // Use of rule 2 to find
        // the optimized answer
        best = min(best, 1 + dp[i - 1]);

        // Store computed value
        dp[i] = best;
    }

    // Return answer
    return dp[n];
}

// Driver Code
int main()
{
    int n = 4;
    cout << downToZero(n);
    return 0;
}
Java
// Java program to implement
// the above approach
class GFG{

// Function to count the minimum
// steps required to reduce n
static int downToZero(int n)
{
    
    // Base case
    if (n <= 3)
        return n;

    // Allocate memory for storing
    // intermediate results
    int []dp = new int[n + 1];
    for(int i = 0; i < n + 1; i++)
        dp[i] = -1;
        
    // Store base values
    dp[0] = 0;
    dp[1] = 1;
    dp[2] = 2;
    dp[3] = 3;

    // Stores square root
    // of each number
    int sqr;
    for(int i = 4; i <= n; i++)
    {
        
        // Compute square root
        sqr = (int)Math.sqrt(i);

        int best = Integer.MAX_VALUE;

        // Use rule 1 to find optimized
        // answer
        while (sqr > 1)
        {

            // Check if it perfectly divides n
            if (i % sqr == 0) 
            {
                best = Math.min(best, 1 + dp[sqr]);
            }
            sqr--;
        }

        // Use of rule 2 to find
        // the optimized answer
        best = Math.min(best, 1 + dp[i - 1]);

        // Store computed value
        dp[i] = best;
    }

    // Return answer
    return dp[n];
}

// Driver Code
public static void main(String[] args)
{
    int n = 4;
    System.out.print(downToZero(n));
}
}

// This code is contributed by amal kumar choubey
 
Python3
# Python3 program to implement
# the above approach
import math
import sys

# Function to count the minimum
# steps required to reduce n
def downToZero(n):

    # Base case
    if (n <= 3):
        return n

    # Allocate memory for storing
    # intermediate results
    dp = [-1] * (n + 1)

    # Store base values
    dp[0] = 0
    dp[1] = 1
    dp[2] = 2
    dp[3] = 3

    # Stores square root
    # of each number
    for i in range(4, n + 1):

        # Compute square root
        sqr = (int)(math.sqrt(i))

        best = sys.maxsize

        # Use rule 1 to find optimized
        # answer
        while (sqr > 1):

            # Check if it perfectly divides n
            if (i % sqr == 0):
                best = min(best, 1 + dp[sqr])
            
            sqr -= 1

        # Use of rule 2 to find
        # the optimized answer
        best = min(best, 1 + dp[i - 1])

        # Store computed value
        dp[i] = best

    # Return answer
    return dp[n]

# Driver Code
if __name__ == "__main__":
    
    n = 4

    print(downToZero(n))

# This code is contributed by chitranayal    
    
C#
// C# program to implement
// the above approach
using System;

class GFG{

// Function to count the minimum
// steps required to reduce n
static int downToZero(int n)
{
    
    // Base case
    if (n <= 3)
        return n;

    // Allocate memory for storing
    // intermediate results
    int []dp = new int[n + 1];
    for(int i = 0; i < n + 1; i++)
        dp[i] = -1;
        
    // Store base values
    dp[0] = 0;
    dp[1] = 1;
    dp[2] = 2;
    dp[3] = 3;

    // Stores square root
    // of each number
    int sqr;
    for(int i = 4; i <= n; i++)
    {
        
        // Compute square root
        sqr = (int)Math.Sqrt(i);

        int best = int.MaxValue;

        // Use rule 1 to find optimized
        // answer
        while (sqr > 1)
        {

            // Check if it perfectly divides n
            if (i % sqr == 0) 
            {
                best = Math.Min(best, 1 + dp[sqr]);
            }
            sqr--;
        }

        // Use of rule 2 to find
        // the optimized answer
        best = Math.Min(best, 1 + dp[i - 1]);

        // Store computed value
        dp[i] = best;
    }

    // Return answer
    return dp[n];
}

// Driver Code
public static void Main(String[] args)
{
    int n = 4;
    Console.Write(downToZero(n));
}
}

// This code is contributed by amal kumar choubey
JavaScript
<script>
    // Javascript Program to implement
    // the above approach
    
    // Function to count the minimum
    // steps required to reduce n
    function downToZero(n)
    {
        // Base case
        if (n <= 3)
            return n;

        // Allocate memory for storing
        // intermediate results
        let dp = new Array(n + 1)
        dp.fill(-1);

        // Store base values
        dp[0] = 0;
        dp[1] = 1;
        dp[2] = 2;
        dp[3] = 3;

        // Stores square root
        // of each number
        let sqr;
        for (let i = 4; i <= n; i++) {

            // Compute square root
            sqr = Math.sqrt(i);

            let best = Number.MAX_VALUE;

            // Use rule 1 to find optimized
            // answer
            while (sqr > 1) {

                // Check if it perfectly divides n
                if (i % sqr == 0) {
                    best = Math.min(best, 1 + dp[sqr]);
                }

                sqr--;
            }

            // Use of rule 2 to find
            // the optimized answer
            best = Math.min(best, 1 + dp[i - 1]);

            // Store computed value
            dp[i] = best;
        }

        // Return answer
        return dp[n];
    }
    
    let n = 4;
    document.write(downToZero(n));
    
    // This code is contributed by divyesh072019.
</script>

Output: 
3

 

Time complexity: O(N * sqrt(n))
Auxiliary Space: O(N) 


Efficient Approach: The idea is to observe that it is possible to replace N by N' where N' = min(a, b) (N = a * b) (a != 1 and b != 1). 

  • If N is even, then the smallest value that divides N is 2. Therefore, directly calculate f(N) = 1 + f(2) = 3.
  • If N is odd, then reduce N by 1 from it i.e N = N - 1. Apply the same logic as used for even numbers. Therefore, for odd numbers, the minimum steps required is 4.


Below is the implementation of the above approach: 
 

C++
// C++ Program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;

// Function to find the minimum
// steps required to reduce n
int downToZero(int n)
{
    // Base case
    if (n <= 3)
        return n;

    // Return answer based on
    // parity of n
    return n % 2 == 0 ? 3 : 4;
}

// Driver Code
int main()
{
    int n = 4;
    cout << downToZero(n);

    return 0;
}
Java
// Java Program to implement
// the above approach
class GFG{
 
// Function to find the minimum
// steps required to reduce n
static int downToZero(int n)
{
    // Base case
    if (n <= 3)
        return n;
 
    // Return answer based on
    // parity of n
    return n % 2 == 0 ? 3 : 4;
}
 
// Driver Code
public static void main(String[] args)
{
    int n = 4;
    System.out.println(downToZero(n));
}
}

// This code is contributed by rock_cool
Python3
# Python3 Program to implement
# the above approach

# Function to find the minimum
# steps required to reduce n
def downToZero(n):
  
    # Base case
    if (n <= 3):
        return n;

    # Return answer based on
    # parity of n
    if(n % 2 == 0):
        return 3;
    else:
        return 4;

# Driver Code
if __name__ == '__main__':
    n = 4;
    print(downToZero(n));
    
# This code is contributed by Rohit_ranjan 
C#
// C# Program to implement
// the above approach
using System;
class GFG{
 
// Function to find the minimum
// steps required to reduce n
static int downToZero(int n)
{
    // Base case
    if (n <= 3)
        return n;
 
    // Return answer based on
    // parity of n
    return n % 2 == 0 ? 3 : 4;
}
 
// Driver Code
public static void Main(String[] args)
{
    int n = 4;
    Console.WriteLine(downToZero(n));
}
}

// This code is contributed by Rajput-Ji 
JavaScript
<script>
    // Javascript Program to implement
    // the above approach
    
    // Function to find the minimum
    // steps required to reduce n
    function downToZero(n)
    {
        // Base case
        if (n <= 3)
            return n;

        // Return answer based on
        // parity of n
        return n % 2 == 0 ? 3 : 4;
    }
    
    let n = 4;
    document.write(downToZero(n));
    
    // This code is contributed by divyeshrabadiya07.
</script>

Output: 
3

 


Time complexity: O(1)
Auxiliary Space: O(1) 


Next Article

Similar Reads