Saturday, September 21, 2024
Google search engine
HomeLanguagesDynamic ProgrammingMinimum moves to make M and N equal by repeated addition of...

Minimum moves to make M and N equal by repeated addition of divisors except 1 using Dynamic Programming

Given two integers N and M, the task is to calculate the minimum number of moves to change N to M, where In one move it is allowed to add any divisor of the current value of N to N itself except 1. Print “-1” if it is not possible.

Example

Input: N = 4, M = 24
Output: 5
Explanation: The given value of N can be converted into M using the following steps: (4)+2 -> (6)+2 -> (8)+4 -> (12)+6 ->  (18)+6 -> 24. Hence, the count of moves is 5 which is the minimum possible.

Input: N = 4, M = 576
Output: 14

 

BFS Approach: The given problem has already been discussed in Set 1 of this article which using the Breadth First Traversal to solve the given problem. 

Approach: This article focused on a different approach based on Dynamic Programming. Below are the steps to follow:

  • Create a 1-D array dp[], where dp[i] stores the minimum number of operations to reach i from N. Initially, dp[N+1… M] = {INT_MAX} and dp[N] = 0.
  • Iterate through the range [N, M] using a variable i and for each i, iterate through all the factors of the given number i. For a factor X, the DP relation can be define as follows:

dp[i + X] = min( dp[i], dp[i + X])

  • The value stored at dp[M] is the required answer.

Below is the implementation of the above approach: 

C++




// C++ implementation for the above approach
#include <bits/stdc++.h>
using namespace std;
  
// Function to find the minimum count of
// operations to convert N to M
int minOperationCnt(int N, int M)
{
  
    // Stores the DP state of the array
    int dp[M + 1];
  
    // Initialize each index with INT_MAX
    for (int i = N + 1; i <= M; i++) {
        dp[i] = INT_MAX;
    }
  
    // Initial condition
    dp[N] = 0;
  
    // Loop to iterate over range [N, M]
    for (int i = N; i <= M; i++) {
  
        // Check if this position
// can be reached or not
        if (dp[i] == INT_MAX) {
            continue;
        }
  
        // Loop to iterate through all divisors
        // of the current value i
        for (int j = 2; j * j <= i; j++) {
  
            // If j is a divisor of i
            if (i % j == 0) {
                if (i + j <= M) {
  
                    // Update the value of dp[i + j]
                    dp[i + j] = min(dp[i + j], dp[i] + 1);
                }
  
                // Check for value i / j;
                if (i + i / j <= M) {
  
                    // Update the value of dp[i + i/j]
                    dp[i + i / j]
                        = min(dp[i + i / j], dp[i] + 1);
                }
            }
        }
    }
  
    // Return Answer
    return (dp[M] == INT_MAX) ? -1 : dp[M];
}
  
// Driver Code
int main()
{
    int N = 4;
    int M = 576;
  
    cout << minOperationCnt(N, M);
  
    return 0;
}


Java




// Java implementation for the above approach
class GFG {
  
    // Function to find the minimum count of
    // operations to convert N to M
    public static int minOperationCnt(int N, int M) {
  
        // Stores the DP state of the array
        int[] dp = new int[M + 1];
  
        // Initialize each index with INT_MAX
        for (int i = N + 1; i <= M; i++) {
            dp[i] = Integer.MAX_VALUE;
        }
  
        // Initial condition
        dp[N] = 0;
  
        // Loop to iterate over range [N, M]
        for (int i = N; i <= M; i++) {
  
            // Check if this position
            // can be reached or not
            if (dp[i] == Integer.MAX_VALUE) {
                continue;
            }
  
            // Loop to iterate through all divisors
            // of the current value i
            for (int j = 2; j * j <= i; j++) {
  
                // If j is a divisor of i
                if (i % j == 0) {
                    if (i + j <= M) {
  
                        // Update the value of dp[i + j]
                        dp[i + j] = Math.min(dp[i + j], dp[i] + 1);
                    }
  
                    // Check for value i / j;
                    if (i + i / j <= M) {
  
                        // Update the value of dp[i + i/j]
                        dp[i + i / j] = Math.min(dp[i + i / j], dp[i] + 1);
                    }
                }
            }
        }
  
        // Return Answer
        return (dp[M] == Integer.MAX_VALUE) ? -1 : dp[M];
    }
  
    // Driver Code
    public static void main(String args[]) {
        int N = 4;
        int M = 576;
  
        System.out.println(minOperationCnt(N, M));
    }
}
  
// This code is contributed by saurabh_jaiswal.


Python3




# python implementation for the above approach
import math
  
INT_MAX = 2147483647
  
# Function to find the minimum count of
# operations to convert N to M
def minOperationCnt(N, M):
  
     # Stores the DP state of the array
    dp = [0 for _ in range(M + 1)]
  
    # Initialize each index with INT_MAX
    for i in range(N+1, M+1):
        dp[i] = INT_MAX
  
        # Initial condition
    dp[N] = 0
  
    # Loop to iterate over range [N, M]
    for i in range(N, M+1):
  
                # Check if this position
        # can be reached or not
        if (dp[i] == INT_MAX):
            continue
  
            # Loop to iterate through all divisors
            # of the current value i
        for j in range(2, int(math.sqrt(i))+1):
  
                        # If j is a divisor of i
            if (i % j == 0):
                if (i + j <= M):
  
                     # Update the value of dp[i + j]
                    dp[i + j] = min(dp[i + j], dp[i] + 1)
  
                    # Check for value i / j;
                if (i + i // j <= M):
  
                     # Update the value of dp[i + i/j]
                    dp[i + i // j] = min(dp[i + i // j], dp[i] + 1)
  
        # Return Answer
    if dp[M] == INT_MAX:
        return -1
    else:
        return dp[M]
  
# Driver Code
if __name__ == "__main__":
  
    N = 4
    M = 576
  
    print(minOperationCnt(N, M))
  
    # This code is contributed by rakeshsahni


C#




// C# implementation for the above approach
using System;
class GFG
{
  
  // Function to find the minimum count of
  // operations to convert N to M
  public static int minOperationCnt(int N, int M)
  {
  
    // Stores the DP state of the array
    int[] dp = new int[M + 1];
  
    // Initialize each index with INT_MAX
    for (int i = N + 1; i <= M; i++)
    {
      dp[i] = int.MaxValue;
    }
  
    // Initial condition
    dp[N] = 0;
  
    // Loop to iterate over range [N, M]
    for (int i = N; i <= M; i++)
    {
  
      // Check if this position
      // can be reached or not
      if (dp[i] == int.MaxValue)
      {
        continue;
      }
  
      // Loop to iterate through all divisors
      // of the current value i
      for (int j = 2; j * j <= i; j++)
      {
  
        // If j is a divisor of i
        if (i % j == 0)
        {
          if (i + j <= M)
          {
  
            // Update the value of dp[i + j]
            dp[i + j] = Math.Min(dp[i + j], dp[i] + 1);
          }
  
          // Check for value i / j;
          if (i + i / j <= M)
          {
  
            // Update the value of dp[i + i/j]
            dp[i + i / j] = Math.Min(dp[i + i / j], dp[i] + 1);
          }
        }
      }
    }
  
    // Return Answer
    return (dp[M] == int.MaxValue) ? -1 : dp[M];
  }
  
  // Driver Code
  public static void Main()
  {
    int N = 4;
    int M = 576;
  
    Console.Write(minOperationCnt(N, M));
  }
}
  
// This code is contributed by saurabh_jaiswal.


Javascript




<script>
 
       // JavaScript Program to implement
       // the above approach 
 
       // Function to find the minimum count of
       // operations to convert N to M
       function minOperationCnt(N, M) {
 
           // Stores the DP state of the array
           let dp = new Array(M + 1)
 
           // Initialize each index with INT_MAX
           for (let i = N + 1; i <= M; i++) {
               dp[i] = Number.MAX_VALUE;
           }
 
           // Initial condition
           dp[N] = 0;
 
           // Loop to iterate over range [N, M]
           for (let i = N; i <= M; i++) {
 
               // Check if this position
               // can be reached or not
               if (dp[i] == Number.MAX_VALUE) {
                   continue;
               }
 
               // Loop to iterate through all divisors
               // of the current value i
               for (let j = 2; j * j <= i; j++) {
 
                   // If j is a divisor of i
                   if (i % j == 0) {
                       if (i + j <= M) {
 
                           // Update the value of dp[i + j]
                           dp[i + j] = Math.min(dp[i + j], dp[i] + 1);
                       }
 
                       // Check for value i / j;
                       if (i + i / j <= M) {
 
                           // Update the value of dp[i + i/j]
                           dp[i + i / j]
                               = Math.min(dp[i + i / j], dp[i] + 1);
                       }
                   }
               }
           }
 
           // Return Answer
           return (dp[M] == Number.MAX_VALUE) ? -1 : dp[M];
       }
 
       // Driver Code
       let N = 4;
       let M = 576;
 
       document.write(minOperationCnt(N, M));
 
   // This code is contributed by Potta Lokesh
   </script>


Output

14

Time Complexity: O((M – N)*√(M – N))
Auxiliary Space: O(M)

Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

RELATED ARTICLES

Most Popular

Recent Comments