Minimum number of operations required to reduce N to 0 - GeeksforGeeks

05 Apr, 2021
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 = 3Output: 3Explanation:Steps involved are 3 -> 2 -> 1 -> 0Therefore, the minimum steps required is 3. Input: N = 4Output: 3Explanation: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++
Java
Python3
C#
Javascript
// C++ Program to implement// the above approach#include <bits/stdc++.h>using namespace std; // Function to count the minimum// steps required to reduce nint 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 Codeint main(){    int n = 4;    cout << downToZero(n);    return 0;}
// Java program to implement// the above approachclass GFG{ // Function to count the minimum// steps required to reduce nstatic 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 Codepublic static void main(String[] args){    int n = 4;    System.out.print(downToZero(n));}} // This code is contributed by amal kumar choubey
# Python3 program to implement# the above approachimport mathimport sys # Function to count the minimum# steps required to reduce ndef 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 Codeif __name__ == "__main__":         n = 4     print(downToZero(n)) # This code is contributed by chitranayal   
// C# program to implement// the above approachusing System; class GFG{ // Function to count the minimum// steps required to reduce nstatic 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 Codepublic static void Main(String[] args){    int n = 4;    Console.Write(downToZero(n));}} // This code is contributed by amal kumar choubey
<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>
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++
Java
Python3
C#
Javascript
// C++ Program to implement// the above approach#include <bits/stdc++.h>using namespace std; // Function to find the minimum// steps required to reduce nint downToZero(int n){    // Base case    if (n <= 3)        return n;     // Return answer based on    // parity of n    return n % 2 == 0 ? 3 : 4;} // Driver Codeint main(){    int n = 4;    cout << downToZero(n);     return 0;}
// Java Program to implement// the above approachclass GFG{  // Function to find the minimum// steps required to reduce nstatic 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 Codepublic static void main(String[] args){    int n = 4;    System.out.println(downToZero(n));}} // This code is contributed by rock_cool
# Python3 Program to implement# the above approach # Function to find the minimum# steps required to reduce ndef 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 Codeif __name__ == '__main__':    n = 4;    print(downToZero(n));     # This code is contributed by Rohit_ranjan
// C# Program to implement// the above approachusing System;class GFG{  // Function to find the minimum// steps required to reduce nstatic 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 Codepublic static void Main(String[] args){    int n = 4;    Console.WriteLine(downToZero(n));}} // This code is contributed by Rajput-Ji
<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>
3
 
Time complexity: O(1)Auxiliary Space: O(1) 
rock_cool
Amal Kumar Choubey
Rajput-Ji
Rohit_ranjan
ukasp
divyeshrabadiya07
divyesh072019
Number Divisibility
Numbers
Dynamic Programming
Greedy
Mathematical
Recursion
Dynamic Programming
Greedy
Mathematical
Recursion
Numbers
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Bellman–Ford Algorithm | DP-23
Floyd Warshall Algorithm | DP-16
Subset Sum Problem | DP-25
Coin Change | DP-7
Longest Palindromic Substring | Set 1
Dijkstra's shortest path algorithm | Greedy Algo-7
Kruskal’s Minimum Spanning Tree Algorithm | Greedy Algo-2
Prim’s Minimum Spanning Tree (MST) | Greedy Algo-5
Program for array rotation
Write a program to print all permutations of a given string