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

• Difficulty Level : Medium
• Last Updated : 23 Nov, 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:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

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 recusrive 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<``int``>(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 recusrive 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 recusrive 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 recusrive 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