Minimum cost to reduce A and B to 0 using square root or divide by 2

• Difficulty Level : Hard
• Last Updated : 28 Dec, 2021

Given two integers A and B, the task is to convert the given two integers to zero at minimal cost by performing the following two types of operations:

• Replace both integers A and B by the square root of the product of A and B. This operation will cost 2 units.
• Replace A by A/2 or B by B/2 respectively. This operation will cost 1 unit.

Example:

Input: A = 2, B = 2
Output: 4
Explanation:
Operation 1: Apply first operation on A, making A=1, B=2. Cost=1
Operation 2: Apply first operation again on A, making A=0, B=2. Cost=2
Operation 3: Apply second operation on both A and B, making A=0, B=0. Cost=4.

Input: A = 53, B = 16
Output: 7

Approach:

This problem can be solved by exploring all possibilities using a recursive tree and then memoizing the solution in a matrix. To solve this problem follow the below steps:

1. Create a function getMinOperations with five parameters that are A, B,   prevA, prevB, and a dp matrix, here prevA and prevB are the previous value of A and B. This function will return the minimum cost required to make A and B to zero.
2. Now, call this function initially with arguments, A, B, prevA = -1, prevB = -1 and dp.
3. In each call:
• First, check if the value of A and B is equal to the value of prevA and prevB. If they are, return INT_MAX from this call as this call is resulting in no change in the values of A and B and therefore will resulting in an infinite recursive loop.
• Check for the base case that is both A and B are zero. If they are, return 0 from this call because the minimum cost to convert A and B to zero is 0 at this stage.
• Also, check if this recursive call is already memorized in the dp matrix. If it is, then return the value from the matrix.
• Now, the answer of every recursive call is the minimum of the answers provided by three subproblems:
• Minimum cost if A is reduced to A/2.
• Minimum cost if B is reduced to B/2.
• Minimum cost if both A and B is reduced to sqrt(A*B).
• Find the minimum of these three values and memoize it while returning from the current recursive call.
4. The function will return the minimum cost after all recursive calls are made.

Below is the implementation of the above approach:

C++

 // C++ program for the above approach   #include using namespace std;   // Function to return the minimum cost // of converting A and B to 0 int getMinOperations(int A, int B,                      int prevA, int prevB,                      vector >& dp) {       // If both A and B doesn't change in     // this recursive call, then return INT_MAX     // to save the code from going into     // infinite loop     if (A == prevA and B == prevB) {         return INT_MAX;     }       // Base Case     if (A == 0 and B == 0) {         return 0;     }       // If the answer of this recursive call     // is already memoised     if (dp[A][B] != -1) {         return dp[A][B];     }       // If A is reduced to A/2     int ans1 = getMinOperations(         A / 2, B, A, B, dp);     if (ans1 != INT_MAX) {         ans1 += 1;     }       // If B is reduced to B/2     int ans2 = getMinOperations(         A, B / 2, A, B, dp);     if (ans2 != INT_MAX) {         ans2 += 1;     }       // If both A and B is reduced to sqrt(A * B)     int ans3 = getMinOperations(sqrt(A * B),                                 sqrt(A * B), A,                                 B, dp);     if (ans3 != INT_MAX) {         ans3 += 2;     }       // Return the minimum of the value given     // by the above three subproblems, also     // memoize the value while returning     return dp[A][B] = min({ ans1, ans2, ans3 }); }   // Driver Code int main() {     int A = 53, B = 16;     int mx = max(A, B);     vector > dp(         mx + 1,         vector(mx + 1, -1));       cout << getMinOperations(         A, B, -1, -1, dp); }

Java

 // Java program for the above approach import java.io.*; class GFG {         // Function to return the minimum cost     // of converting A and B to 0     static int getMinOperations(int A, int B, int prevA,                                 int prevB, int dp[][])     {           // If both A and B doesn't change in         // this recursive call, then return INT_MAX         // to save the code from going into         // infinite loop         if (A == prevA && B == prevB) {             return Integer.MAX_VALUE;         }           // Base Case         if (A == 0 && B == 0) {             return 0;         }           // If the answer of this recursive call         // is already memoised         if (dp[A][B] != -1) {             return dp[A][B];         }           // If A is reduced to A/2         int ans1 = getMinOperations(A / 2, B, A, B, dp);         if (ans1 != Integer.MAX_VALUE) {             ans1 += 1;         }           // If B is reduced to B/2         int ans2 = getMinOperations(A, B / 2, A, B, dp);         if (ans2 != Integer.MAX_VALUE) {             ans2 += 1;         }           // If both A and B is reduced to sqrt(A * B)         int ans3 = getMinOperations((int)Math.sqrt(A * B),                                     (int)Math.sqrt(A * B),                                     A, B, dp);         if (ans3 != Integer.MAX_VALUE) {             ans3 += 2;         }         // Return the minimum of the value given         // by the above three subproblems, also         // memoize the value while returning         return dp[A][B]             = Math.min(ans1, Math.min(ans2, ans3));     }         // Driver Code     public static void main(String[] args)     {         int A = 53, B = 16;         int mx = Math.max(A, B);         int dp[][] = new int[mx + 1][mx + 1];         for (int i = 0; i <= mx; i++) {             for (int j = 0; j <= mx; j++)                 dp[i][j] = -1;         }         System.out.println(             getMinOperations(A, B, -1, -1, dp));     } }   // This code is contributed by dwivediyash

Python3

 # Python program for the above approach import math as Math   # Function to return the minimum cost # of converting A and B to 0 def getMinOperations(A, B, prevA, prevB, dp):       # If both A and B doesn't change in   # this recursive call, then return INT_MAX   # to save the code from going into   # infinite loop   if (A == prevA and B == prevB):     return 10**9;       # Base Case   if (A == 0 and B == 0):     return 0;       # If the answer of this recursive call   # is already memoised   if (dp[A][B] != -1):     return dp[A][B];       # If A is reduced to A/2   ans1 = getMinOperations(A // 2, B, A, B, dp);   if (ans1 != 10**9):     ans1 += 1;       # If B is reduced to B/2   ans2 = getMinOperations(A, B // 2, A, B, dp);   if (ans2 != 10**9):     ans2 += 1;       # If both A and B is reduced to sqrt(A * B)   ans3 = getMinOperations(     Math.floor(Math.sqrt(A * B)),     Math.floor(Math.sqrt(A * B)),     A,     B,     dp   );   if (ans3 != 10**9):     ans3 += 2;       # Return the minimum of the value given   # by the above three subproblems, also   # memoize the value while returning   dp[A][B] = min(ans1, min(ans2, ans3))   return dp[A][B];   # Driver Code A = 53 B = 16 mx = max(A, B); dp = [[-1 for i in range(mx + 1)] for i in range(mx + 1)]   print(getMinOperations(A, B, -1, -1, dp));   # This code is contributed by gfgking.

C#

 // C# program for the above approach using System; using System.Collections; class GFG {         // Function to return the minimum cost     // of converting A and B to 0     static int getMinOperations(int A, int B, int prevA,                                 int prevB, int [,]dp)     {           // If both A and B doesn't change in         // this recursive call, then return INT_MAX         // to save the code from going into         // infinite loop         if (A == prevA && B == prevB) {             return Int32.MaxValue;         }           // Base Case         if (A == 0 && B == 0) {             return 0;         }           // If the answer of this recursive call         // is already memoised         if (dp[A, B] != -1) {             return dp[A, B];         }           // If A is reduced to A/2         int ans1 = getMinOperations(A / 2, B, A, B, dp);         if (ans1 != Int32.MaxValue) {             ans1 += 1;         }           // If B is reduced to B/2         int ans2 = getMinOperations(A, B / 2, A, B, dp);         if (ans2 != Int32.MaxValue) {             ans2 += 1;         }           // If both A and B is reduced to sqrt(A * B)         int ans3 = getMinOperations((int)Math.Sqrt(A * B),                                     (int)Math.Sqrt(A * B),                                     A, B, dp);         if (ans3 != Int32.MaxValue) {             ans3 += 2;         }         // Return the minimum of the value given         // by the above three subproblems, also         // memoize the value while returning         return dp[A, B]             = Math.Min(ans1, Math.Min(ans2, ans3));     }         // Driver Code     public static void Main()     {         int A = 53, B = 16;         int mx = Math.Max(A, B);         int [,]dp = new int[mx + 1, mx + 1];         for (int i = 0; i <= mx; i++) {             for (int j = 0; j <= mx; j++)                 dp[i, j] = -1;         }         Console.Write(             getMinOperations(A, B, -1, -1, dp));     } }   // This code is contributed by Samim Hossain Mondal.

Javascript



Output

7

Time Complexity: O(max(A, B)^2)
Auxiliary Space: O(max(A, B)^2)

My Personal Notes arrow_drop_up
Recommended Articles
Page :