Minimum number of operations required to reduce N to 0
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++
#include <bits/stdc++.h>
using namespace std;
int downToZero( int n)
{
if (n <= 3)
return n;
vector< int > dp(n + 1, -1);
dp[0] = 0;
dp[1] = 1;
dp[2] = 2;
dp[3] = 3;
int sqr;
for ( int i = 4; i <= n; i++) {
sqr = sqrt (i);
int best = INT_MAX;
while (sqr > 1) {
if (i % sqr == 0) {
best = min(best, 1 + dp[sqr]);
}
sqr--;
}
best = min(best, 1 + dp[i - 1]);
dp[i] = best;
}
return dp[n];
}
int main()
{
int n = 4;
cout << downToZero(n);
return 0;
}
|
Java
class GFG{
static int downToZero( int n)
{
if (n <= 3 )
return n;
int []dp = new int [n + 1 ];
for ( int i = 0 ; i < n + 1 ; i++)
dp[i] = - 1 ;
dp[ 0 ] = 0 ;
dp[ 1 ] = 1 ;
dp[ 2 ] = 2 ;
dp[ 3 ] = 3 ;
int sqr;
for ( int i = 4 ; i <= n; i++)
{
sqr = ( int )Math.sqrt(i);
int best = Integer.MAX_VALUE;
while (sqr > 1 )
{
if (i % sqr == 0 )
{
best = Math.min(best, 1 + dp[sqr]);
}
sqr--;
}
best = Math.min(best, 1 + dp[i - 1 ]);
dp[i] = best;
}
return dp[n];
}
public static void main(String[] args)
{
int n = 4 ;
System.out.print(downToZero(n));
}
}
|
Python3
import math
import sys
def downToZero(n):
if (n < = 3 ):
return n
dp = [ - 1 ] * (n + 1 )
dp[ 0 ] = 0
dp[ 1 ] = 1
dp[ 2 ] = 2
dp[ 3 ] = 3
for i in range ( 4 , n + 1 ):
sqr = ( int )(math.sqrt(i))
best = sys.maxsize
while (sqr > 1 ):
if (i % sqr = = 0 ):
best = min (best, 1 + dp[sqr])
sqr - = 1
best = min (best, 1 + dp[i - 1 ])
dp[i] = best
return dp[n]
if __name__ = = "__main__" :
n = 4
print (downToZero(n))
|
C#
using System;
class GFG{
static int downToZero( int n)
{
if (n <= 3)
return n;
int []dp = new int [n + 1];
for ( int i = 0; i < n + 1; i++)
dp[i] = -1;
dp[0] = 0;
dp[1] = 1;
dp[2] = 2;
dp[3] = 3;
int sqr;
for ( int i = 4; i <= n; i++)
{
sqr = ( int )Math.Sqrt(i);
int best = int .MaxValue;
while (sqr > 1)
{
if (i % sqr == 0)
{
best = Math.Min(best, 1 + dp[sqr]);
}
sqr--;
}
best = Math.Min(best, 1 + dp[i - 1]);
dp[i] = best;
}
return dp[n];
}
public static void Main(String[] args)
{
int n = 4;
Console.Write(downToZero(n));
}
}
|
Javascript
<script>
function downToZero(n)
{
if (n <= 3)
return n;
let dp = new Array(n + 1)
dp.fill(-1);
dp[0] = 0;
dp[1] = 1;
dp[2] = 2;
dp[3] = 3;
let sqr;
for (let i = 4; i <= n; i++) {
sqr = Math.sqrt(i);
let best = Number.MAX_VALUE;
while (sqr > 1) {
if (i % sqr == 0) {
best = Math.min(best, 1 + dp[sqr]);
}
sqr--;
}
best = Math.min(best, 1 + dp[i - 1]);
dp[i] = best;
}
return dp[n];
}
let n = 4;
document.write(downToZero(n));
</script>
|
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++
#include <bits/stdc++.h>
using namespace std;
int downToZero( int n)
{
if (n <= 3)
return n;
return n % 2 == 0 ? 3 : 4;
}
int main()
{
int n = 4;
cout << downToZero(n);
return 0;
}
|
Java
class GFG{
static int downToZero( int n)
{
if (n <= 3 )
return n;
return n % 2 == 0 ? 3 : 4 ;
}
public static void main(String[] args)
{
int n = 4 ;
System.out.println(downToZero(n));
}
}
|
Python3
def downToZero(n):
if (n < = 3 ):
return n;
if (n % 2 = = 0 ):
return 3 ;
else :
return 4 ;
if __name__ = = '__main__' :
n = 4 ;
print (downToZero(n));
|
C#
using System;
class GFG{
static int downToZero( int n)
{
if (n <= 3)
return n;
return n % 2 == 0 ? 3 : 4;
}
public static void Main(String[] args)
{
int n = 4;
Console.WriteLine(downToZero(n));
}
}
|
Javascript
<script>
function downToZero(n)
{
if (n <= 3)
return n;
return n % 2 == 0 ? 3 : 4;
}
let n = 4;
document.write(downToZero(n));
</script>
|
Time complexity: O(1)
Auxiliary Space: O(1)
Last Updated :
05 Apr, 2021
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...