Minimum cost to convert M to N by repeated addition of its even divisors
Last Updated :
19 Dec, 2023
Given two integers M and N, the task is to find the minimum cost to convert M to N by repetitive addition of even divisors of the current value of M (except M).
The cost to add an even divisor of the current value of M, say d, is equal to M / d.
Print “-1” if it is impossible to convert M to N.
Examples:
Input: M = 6, N = 24
Output: 10
Explanation:
Step 1: M = 6 + 2 = 8, Cost = (6 / 2) = 3
Step 2: M = 8 + 4 = 12, Cost = 3 + (8 / 2) = 5
Step 3: M = 12 + 6 = 18, Cost = 5 + (12/ 6) = 7
Step 4: M = 18 + 6 = 24, Cost = 7 + (18 / 6) = 10
Therefore, the minimum cost to convert M to N is equal to 10.
Input: M = 9, N = 17
Output: -1
Explanation:
Since there are no even divisors of 9, therefore, conversion is not possible.
Naive approach: The simplest approach is to iterate through all possible even divisors of given number M and recursively calculate the minimum cost to change M to N. The recurrence relation formed is given by:
min_cost = Math.min(min_cost, m / i + minSteps(m + i, n))
Below is the implementation of the above approach :
C++
#include <iostream>
using namespace std;
int inf = 1000000008;
int minSteps( int m, int n)
{
if (n == m)
return 0;
if (m > n)
return inf;
int min_cost = inf;
for ( int i = 2; i < m; i += 2)
{
if (m % i == 0)
{
min_cost = min(min_cost,
m / i +
minSteps(m + i, n));
}
}
return min_cost;
}
int main()
{
int M = 6;
int N = 24;
int minimum_cost = minSteps(M, N);
if (minimum_cost == inf)
minimum_cost = -1;
cout << minimum_cost;
return 0;
}
|
Java
import java.util.*;
public class GFG {
static int inf = 1000000008 ;
public static int
minSteps( int m, int n)
{
if (n == m)
return 0 ;
if (m > n)
return inf;
int min_cost = inf;
for ( int i = 2 ; i < m; i += 2 ) {
if (m % i == 0 ) {
min_cost
= Math.min(
min_cost,
m / i
+ minSteps(m + i, n));
}
}
return min_cost;
}
public static void
main(String args[])
{
int M = 6 ;
int N = 24 ;
int minimum_cost
= minSteps(M, N);
minimum_cost
= minimum_cost
== inf
? - 1
: minimum_cost;
System.out.println(minimum_cost);
}
}
|
Python3
inf = 1000000008
def minSteps(m, n):
if (n = = m):
return 0
if (m > n):
return inf
min_cost = inf
for i in range ( 2 , m, 2 ):
if (m % i = = 0 ):
min_cost = min (min_cost, m / i +
minSteps(m + i, n))
return min_cost
if __name__ = = '__main__' :
M = 6
N = 24
minimum_cost = minSteps(M, N)
if minimum_cost = = inf:
minimum_cost = - 1
print (minimum_cost)
|
C#
using System;
class GFG{
static int inf = 1000000008;
public static int minSteps( int m,
int n)
{
if (n == m)
return 0;
if (m > n)
return inf;
int min_cost = inf;
for ( int i = 2; i < m; i += 2)
{
if (m % i == 0)
{
min_cost = Math.Min(min_cost, m / i +
minSteps(m + i, n));
}
}
return min_cost;
}
public static void Main(String []args)
{
int M = 6;
int N = 24;
int minimum_cost = minSteps(M, N);
minimum_cost = minimum_cost == inf ? -1 :
minimum_cost;
Console.WriteLine(minimum_cost);
}
}
|
Javascript
<script>
let inf = 1000000008;
function
minSteps(m, n)
{
if (n == m)
return 0;
if (m > n)
return inf;
let min_cost = inf;
for (let i = 2; i < m; i += 2) {
if (m % i == 0) {
min_cost
= Math.min(
min_cost,
m / i
+ minSteps(m + i, n));
}
}
return min_cost;
}
let M = 6;
let N = 24;
let minimum_cost
= minSteps(M, N);
minimum_cost
= minimum_cost
== inf
? -1
: minimum_cost;
document.write(minimum_cost);
</script>
|
Time Complexity: O(2N)
Auxiliary Space: O(2N) for recursive call stack
Efficient Approach: The above approach can be optimized by using dynamic programming and memoization to the above implementation. Instead of computing the states again and again store it in an array dp[] and use it when required.
dp(m) = min(dp(m), (m/i) + dp(m+i)) for all even divisors of m less than m
Below is the implementation of the above approach:
C++
#include <iostream>
using namespace std;
int inf = 1000000008;
int minStepsUtil( int m, int n, int dp[])
{
if (n == m)
return 0;
if (m > n)
return inf;
if (dp[m] != inf)
return dp[m];
int min_cost = inf;
for ( int i = 2; i < m; i += 2)
{
if (m % i == 0)
{
min_cost = min(min_cost,
m / i +
minStepsUtil(m + i,
n, dp));
}
}
return dp[m] = min_cost;
}
void minSteps( int M, int N)
{
int dp[N + 5];
for ( int i = 0; i < N + 5; i++)
{
dp[i] = inf;
}
int minimum_cost = minStepsUtil(M, N, dp);
if (minimum_cost == inf)
minimum_cost = -1;
cout << minimum_cost;
}
int main()
{
int M = 6;
int N = 24;
minSteps(M, N);
}
|
Java
import java.util.*;
public class GFG {
static int inf = 1000000008 ;
public static int
minStepsUtil( int m, int n, int dp[])
{
if (n == m)
return 0 ;
if (m > n)
return inf;
if (dp[m] != inf)
return dp[m];
int min_cost = inf;
for ( int i = 2 ; i < m; i += 2 ) {
if (m % i == 0 ) {
min_cost = Math.min(
min_cost,
m / i
+ minStepsUtil(m + i, n, dp));
}
}
return dp[m] = min_cost;
}
public static void
minSteps( int M, int N)
{
int dp[] = new int [N + 5 ];
Arrays.fill(dp, inf);
int minimum_cost
= minStepsUtil(M, N, dp);
minimum_cost
= minimum_cost
== inf
? - 1
: minimum_cost;
System.out.println(minimum_cost);
}
public static void main(String args[])
{
int M = 6 ;
int N = 24 ;
minSteps(M, N);
}
}
|
Python3
inf = 1000000008 ;
def minStepsUtil(m, n, dp):
if (n = = m):
return 0 ;
if (m > n):
return inf;
if (dp[m] ! = inf):
return dp[m];
min_cost = inf;
for i in range ( 2 ,m, 2 ):
if (m % i = = 0 ):
min_cost = min (min_cost, m / / i + minStepsUtil(m + i, n, dp));
dp[m] = min_cost
return dp[m];
def minSteps(M, N):
dp = [inf] * (N + 5 );
minimum_cost = minStepsUtil(M, N, dp);
minimum_cost = - 1 if minimum_cost = = inf else minimum_cost;
print (minimum_cost);
if __name__ = = '__main__' :
M = 6 ;
N = 24 ;
minSteps(M, N);
|
C#
using System;
class GFG{
static int inf = 1000000008;
public static int minStepsUtil( int m,
int n, int []dp)
{
if (n == m)
return 0;
if (m > n)
return inf;
if (dp[m] != inf)
return dp[m];
int min_cost = inf;
for ( int i = 2; i < m; i += 2)
{
if (m % i == 0)
{
min_cost = Math.Min(min_cost, m / i +
minStepsUtil(m + i,
n, dp));
}
}
return dp[m] = min_cost;
}
public static void minSteps( int M,
int N)
{
int []dp = new int [N + 5];
for ( int i = 0; i < dp.GetLength(0);
i++)
dp[i] = inf;
int minimum_cost = minStepsUtil(M, N, dp);
minimum_cost = minimum_cost ==
inf ? -1 : minimum_cost;
Console.WriteLine(minimum_cost);
}
public static void Main(String []args)
{
int M = 6;
int N = 24;
minSteps(M, N);
}
}
|
Javascript
<script>
var inf = 1000000008;
function minStepsUtil(m, n, dp)
{
if (n == m)
return 0;
if (m > n)
return inf;
if (dp[m] != inf)
return dp[m];
var min_cost = inf;
for ( var i = 2; i < m; i += 2)
{
if (m % i == 0)
{
min_cost = Math.min(min_cost,
m / i +
minStepsUtil(m + i,
n, dp));
}
}
return dp[m] = min_cost;
}
function minSteps(M, N)
{
var dp = Array(N+5);
for ( var i = 0; i < N + 5; i++)
{
dp[i] = inf;
}
var minimum_cost = minStepsUtil(M, N, dp);
if (minimum_cost == inf)
minimum_cost = -1;
document.write( minimum_cost);
}
var M = 6;
var N = 24;
minSteps(M, N);
</script>
|
Time Complexity: O(Nlog(M))
Auxiliary Space: O(N)
Another approach : Using DP Tabulation method ( Iterative approach )
The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memoization(top-down) because memoization method needs extra stack space of recursion calls.
Steps to solve this problem :
- Create a table DP to store the solution of the subproblems and initialize it with INF.
- Initialize the table DP with base cases
- Now Iterate over subproblems to get the value of current problem form previous computation of subproblems stored in DP.
- Return the final solution is present stored in dp[n].
Implementation :
C++
#include <iostream>
#include <cstring>
using namespace std;
const int INF = 1000000008;
void minSteps( int M, int N) {
int dp[N+5];
memset (dp, INF, sizeof (dp));
dp[M] = 0;
for ( int i = M; i <= N; i++) {
for ( int j = 2; j < i; j += 2) {
if (i % j == 0) {
dp[i+j] = min(dp[i+j], dp[i] + i/j);
}
}
}
if (dp[N] == INF) {
cout << "-1" ;
} else {
cout << dp[N];
}
}
int main() {
int M = 6;
int N = 24;
minSteps(M, N);
return 0;
}
|
Java
import java.io.*;
public class GFG {
static final int INF = 1000000008 ;
static void minSteps( int M, int N) {
int [] dp = new int [N + 5 ];
for ( int i = 0 ; i < dp.length; i++) {
dp[i] = INF;
}
dp[M] = 0 ;
for ( int i = M; i <= N; i++) {
for ( int j = 2 ; (i + j) < dp.length && j < i; j += 2 ) {
if (i % j == 0 ) {
dp[i + j] = Math.min(dp[i + j], dp[i] + i / j);
}
}
}
if (dp[N] == INF) {
System.out.println( "-1" );
} else {
System.out.println(dp[N]);
}
}
public static void main(String[] args) {
int M = 6 ;
int N = 24 ;
minSteps(M, N);
}
}
|
Python3
INF = 1000000008
def minSteps(M, N):
dp = [INF] * (N + 5 )
dp[M] = 0
for i in range (M, N + 1 - M):
for j in range ( 2 , i, 2 ):
if i % j = = 0 :
dp[i + j] = min (dp[i + j], dp[i] + i / / j)
if dp[N] = = INF:
print ( "-1" )
else :
print (dp[N])
M = 6
N = 24
minSteps(M, N)
|
C#
using System;
class Program {
const int INF = 1000000008;
static void MinSteps( int M, int N)
{
int [] dp = new int [N + 5];
for ( int i = 0; i < dp.Length; i++) {
dp[i] = INF;
}
dp[M] = 0;
for ( int i = M; i <= N - M; i++) {
for ( int j = 2; j < i; j += 2) {
if (i % j == 0) {
dp[i + j] = Math.Min(dp[i + j],
dp[i] + i / j);
}
}
}
if (dp[N] == INF) {
Console.WriteLine( "-1" );
}
else {
Console.WriteLine(dp[N]);
}
}
static void Main()
{
int M = 6;
int N = 24;
MinSteps(M, N);
}
}
|
Javascript
function minSteps(M, N) {
const INF = 1000000008;
let dp = new Array(N+5).fill(INF);
dp[M] = 0;
for (let i = M; i <= N; i++) {
for (let j = 2; j < i; j += 2) {
if (i % j == 0) {
dp[i+j] = Math.min(dp[i+j], dp[i] + i/j);
}
}
}
if (dp[N] == INF) {
console.log( "-1" );
} else {
console.log(dp[N]);
}
}
let M = 6;
let N = 24;
minSteps(M, N);
|
Time complexity: O(N*N)
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...