Max Money Exchange with n/2, n/3, and n/4

Last Updated : 8 Jul, 2026

Ritika has a coin worth n dollars.  she can exchange any coin worth n at the bank into three separate coins worth n/2, n/3, and n/4 (each value rounded down, i.e., integer division). She keeps exchanging coins wherever it results in profit.

Find the maximum total amount of money Ritika can end up with.

Examples:

Input: n = 5
Output: 5
Explanation: 5 => 5 / 2 + 5 / 3 + 5 / 4 = 2 + 1 + 1 = 4 (< 5), so exchanging gives a loss.
Hence, the maximum amount she can have is 5 itself (no exchange).

Input: n = 12
Output: 13
Explanation: 12 => 12 / 2 + 12 / 3 + 12 / 4 = 6 + 4 + 3 = 13 (> 12), so she exchanges.
None of 6, 4, or 3 can be exchanged further for profit.
Hence, the maximum amount is 13.

Try It Yourself
redirect icon

[Naive Approach] Try Every Exchange Recursively - O(3^k) Time and O(k) Space

The idea is to recursively compute the maximum money obtained by either keeping the current coin or exchanging it into n/2, n/3, and n/4. Since the same coin values are solved repeatedly, this approach performs many duplicate computations.

C++
#include <algorithm>
#include <iostream>
using namespace std;

int maxExchangeMoney(int n)
{

    // Base case
    if (n == 0)
        return 0;

    // Compute money obtained after exchange
    int exchanged = maxExchangeMoney(n / 2) + maxExchangeMoney(n / 3) + maxExchangeMoney(n / 4);

    // Return the better option
    return max(n, exchanged);
}

int main()
{
    int n = 12;

    cout << maxExchangeMoney(n);

    return 0;
}
Java
class GFG {
    
    public int maxExchangeMoney(int n)
    {

        // Base case
        if (n == 0)
            return 0;

        // Compute money obtained after exchange
        int exchanged = maxExchangeMoney(n / 2)
                        + maxExchangeMoney(n / 3)
                        + maxExchangeMoney(n / 4);

        // Return the better option
        return Math.max(n, exchanged);
    }

    public static void main(String[] args)
    {
        int n = 12;

        GFG obj = new GFG();
        System.out.println(obj.maxExchangeMoney(n));
    }
}
Python
def maxExchangeMoney(n):

    # Base case
    if n == 0:
        return 0

    # Compute money obtained after exchange
    exchanged = maxExchangeMoney(
        n // 2) + maxExchangeMoney(n // 3) + maxExchangeMoney(n // 4)

    # Return the better option
    return max(n, exchanged)


if __name__ == '__main__':
    n = 12

    print(maxExchangeMoney(n))
C#
using System;

class GFG {
    public int maxExchangeMoney(int n)
    {

        // Base case
        if (n == 0)
            return 0;

        // Compute money obtained after exchange
        int exchanged = maxExchangeMoney(n / 2)
                        + maxExchangeMoney(n / 3)
                        + maxExchangeMoney(n / 4);

        // Return the better option
        return Math.Max(n, exchanged);
    }

    static void Main()
    {
        int n = 12;

        GFG obj = new GFG();
        Console.WriteLine(obj.maxExchangeMoney(n));
    }
}
JavaScript
function maxExchangeMoney(n)
{

    // Base case
    if (n === 0)
        return 0;

    // Compute money obtained after exchange
    let exchanged = maxExchangeMoney(Math.floor(n / 2))
                    + maxExchangeMoney(Math.floor(n / 3))
                    + maxExchangeMoney(Math.floor(n / 4));

    // Return the better option
    return Math.max(n, exchanged);
}

// Driver Code
let n = 12;

console.log(maxExchangeMoney(n));

Output
13

[Better Approach] Dynamic Programming (Memoization using Array) - O(n) Time and O(n) Space

The idea is to store the maximum money for every coin value in a DP array. Before solving a coin, check whether its answer is already computed. This avoids repeated recursive calculations.

Working of Approach:

  • Create a DP array dp of size n + 1 and initialize all values to -1 to indicate that no state has been computed yet.
  • Recursively compute the maximum money for a coin of value n. Before solving a state, check whether its value is already stored in dp.
  • If the value is not computed, recursively find the maximum money obtainable from n/2, n/3, and n/4, and add their results.
  • Compare the exchanged value with the original coin value and store the larger value in dp[n].
  • Return the stored result. Since each coin value is computed only once, repeated recursive calculations are avoided.
C++
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

vector<int> dp;

// Function to return maximum exchange money
int findMaxExc(int n)
{

    // Base case
    if (n == 0)
        return 0;

    // Return already computed answer
    if (dp[n] != -1)
        return dp[n];

    // Compute money obtained after exchange
    int exchanged = findMaxExc(n / 2) + findMaxExc(n / 3) + findMaxExc(n / 4);

    // Store and return the best answer
    return dp[n] = max(n, exchanged);
}

int maxExchangeMoney(int n)
{

    // Initialize DP array
    dp.assign(n + 1, -1);

    return findMaxExc(n);
}

int main()
{
    int n = 12;

    cout << maxExchangeMoney(n);

    return 0;
}
Java
import java.util.Arrays;

class GFG {

    // DP array to store previously computed results
    int[] dp;

    // Function to return maximum exchange money
    int findMaxExc(int n)
    {

        // Base case
        if (n == 0)
            return 0;

        // Return already computed answer
        if (dp[n] != -1)
            return dp[n];

        // Compute money obtained after exchange
        int exchanged = findMaxExc(n / 2) + findMaxExc(n / 3) + findMaxExc(n / 4);

        // Store and return the best answer
        return dp[n] = Math.max(n, exchanged);
    }

    // Function to return maximum exchange money
    public int maxExchangeMoney(int n)
    {

        // Initialize DP array
        dp = new int[n + 1];
        Arrays.fill(dp, -1);

        return findMaxExc(n);
    }

    public static void main(String[] args)
    {
        int n = 12;

        GFG obj = new GFG();
        System.out.println(obj.maxExchangeMoney(n));
    }
}
Python
dp = [-1]

# Function to return maximum exchange money
def findMaxExc(n):

    # Base case
    if n == 0:
        return 0

    # Return already computed answer
    if dp[n] != -1:
        return dp[n]

    # Compute money obtained after exchange
    exchanged = findMaxExc(n // 2) + findMaxExc(n // 3) + findMaxExc(n // 4)

    # Store and return the best answer
    dp[n] = max(n, exchanged)
    return dp[n]


def maxExchangeMoney(n):

    # Initialize DP array
    global dp
    dp = [-1] * (n + 1)

    return findMaxExc(n)


if __name__ == '__main__':
    n = 12
    print(maxExchangeMoney(n))
C#
using System;

class GFG {

    // DP array to store previously computed results
    int[] dp;

    // Function to return maximum exchange money
    int findMaxExc(int n)
    {

        // Base case
        if (n == 0)
            return 0;

        // Return already computed answer
        if (dp[n] != -1)
            return dp[n];

        // Compute money obtained after exchange
        int exchanged = findMaxExc(n / 2) + findMaxExc(n / 3) + findMaxExc(n / 4);

        // Store and return the best answer
        return dp[n] = Math.Max(n, exchanged);
    }

    // Function to return maximum exchange money
    public int maxExchangeMoney(int n)
    {

        // Initialize DP array
        dp = new int[n + 1];
        Array.Fill(dp, -1);

        return findMaxExc(n);
    }

    static void Main()
    {
        int n = 12;

        GFG obj = new GFG();
        Console.WriteLine(obj.maxExchangeMoney(n));
    }
}
JavaScript
let dp = [];

// Function to return maximum exchange money
function findMaxExc(n)
{

    // Base case
    if (n === 0) {
        return 0;
    }

    // Return already computed answer
    if (dp[n] !== -1) {
        return dp[n];
    }

    // Compute money obtained after exchange
    let exchanged = findMaxExc(Math.floor(n / 2)) + findMaxExc(Math.floor(n / 3))  + findMaxExc(Math.floor(n / 4));

    // Store and return the best answer
    return dp[n] = Math.max(n, exchanged);
}

function maxExchangeMoney(n)
{

    // Initialize DP array
    dp = new Array(n + 1).fill(-1);

    return findMaxExc(n);
}

// Driver Code
let n = 12;
console.log(maxExchangeMoney(n));

Output
13

[Expected Approach] Dynamic Programming (Memoization using Hash Map) - O(S) Time and O(S) Space

The idea is to use an unordered_map to memoize only the coin values that are actually visited during recursion. This avoids duplicate computations while using much less memory than a DP array, making it suitable for large values of n.

Let us understand with an example:
Input: n = 12

  • Start with n = 12. Since 12 ≥ 12, recursively compute maxExchangeMoney(6) + maxExchangeMoney(4) + maxExchangeMoney(3).
  • The values 6, 4, and 3 are all smaller than 12, so they cannot be exchanged further and return 6, 4, and 3 respectively.
  • The total money obtained after exchange is 6 + 4 + 3 = 13.
  • Compare the exchanged value with the original coin value: max(12, 13) = 13.
  • Store 13 in the hash map for coin 12 and return 13 as the final answer.
C++
#include <algorithm>
#include <iostream>
#include <unordered_map>
using namespace std;

// map to store previously calculated
// results for optimization
unordered_map<int, int> mp;

// Function to calculate the maximum exchange money
int maxExchangeMoney(int n)
{
    // if result for n is already computed,
    // return it directly
    if (mp.find(n) != mp.end())
        return mp[n];

    // base case: coins smaller than 12 cannot 
    // be exchanged for profit
    if (n < 12)
        return n;

    // recursively compute exchange value by 
    // splitting into n/2, n/3, n/4
    int change = maxExchangeMoney(n / 2) + maxExchangeMoney(n / 3) + maxExchangeMoney(n / 4);

    // take the maximum of exchanged value and
    // the original coin value
    change = max(change, n);

    // store result in map before returning
    mp[n] = change;

    return change;
}

int main()
{
    int n = 12;

    cout << maxExchangeMoney(n);

    return 0;
}
Java
import java.util.HashMap;

class GFG {

    // Map to store previously computed results
    HashMap<Integer, Integer> memo = new HashMap<>();

    // Function to calculate the 
    // maximum exchange money
    public int maxExchangeMoney(int n)
    {

        // Return the stored result if 
        // already computed
        if (memo.containsKey(n))
            return memo.get(n);

        // Coins smaller than 12 cannot 
        // be exchanged for profit
        if (n < 12)
            return n;

        // Compute the maximum value obtained after
        // exchanging the coin
        int exchange = maxExchangeMoney(n / 2)
                       + maxExchangeMoney(n / 3)
                       + maxExchangeMoney(n / 4);

        // Choose the better option between exchanging and
        // keeping the coin
        int result = Math.max(n, exchange);

        // Store the result for future use
        memo.put(n, result);

        return result;
    }

    public static void main(String[] args)
    {
        int n = 12;

        GFG obj = new GFG();
        System.out.println(obj.maxExchangeMoney(n));
    }
}
Python
from math import floor

# map to store previously calculated 
# results for optimization
mp = {}

# Function to calculate the maximum
# exchange money
def maxExchangeMoney(n):
    # if result for n is already computed, 
    # return it directly
    if n in mp:
        return mp[n]

    # base case: coins smaller than 12 cannot
    # be exchanged for profit
    if n < 12:
        return n

    # recursively compute exchange value by 
    # splitting into n/2, n/3, n/4
    change = maxExchangeMoney(
        floor(n / 2)) + maxExchangeMoney(floor(n / 3)) + maxExchangeMoney(floor(n / 4))

    # take the maximum of exchanged value 
    # and the original coin value
    change = max(change, n)

    # store result in map before returning
    mp[n] = change

    return change


if __name__ == '__main__':
    n = 12

    print(maxExchangeMoney(n))
C#
using System;
using System.Collections.Generic;

class GFG {

    // Map to store previously computed results
    Dictionary<int, int> memo = new Dictionary<int, int>();

    // Function to calculate the maximum 
    // exchange money
    public int maxExchangeMoney(int n)
    {

        // Return the stored result if already computed
        if (memo.ContainsKey(n))
            return memo[n];

        // Coins smaller than 12 cannot be 
        // exchanged for profit
        if (n < 12)
            return n;

        // Compute the maximum value obtained after
        // exchanging the coin
        int exchange = maxExchangeMoney(n / 2)
                       + maxExchangeMoney(n / 3)
                       + maxExchangeMoney(n / 4);

        // Choose the better option between exchanging and
        // keeping the coin
        int result = Math.Max(n, exchange);

        // Store the result for future use
        memo[n] = result;

        return result;
    }


    static void Main()
    {
        int n = 12;

        GFG obj = new GFG();
        Console.WriteLine(obj.maxExchangeMoney(n));
    }
}
JavaScript
// map to store previously calculated results for
// optimization
const mp = new Map();

// Function to calculate the
// maximum exchange money
function maxExchangeMoney(n)
{
    // if result for n is already computed, return it
    // directly
    if (mp.has(n)) {
        return mp.get(n);
    }

    // base case: coins smaller than 12
    // cannot be exchanged for profit
    if (n < 12) {
        return n;
    }

    // recursively compute exchange value 
    // by splitting into n/2, n/3, n/4
    let change = maxExchangeMoney(Math.floor(n / 2))
                 + maxExchangeMoney(Math.floor(n / 3))
                 + maxExchangeMoney(Math.floor(n / 4));

    // take the maximum of exchanged value and the original
    // coin value
    change = Math.max(change, n);

    // store result in map before returning
    mp.set(n, change);

    return change;
}

// Driver Code
const n = 12;
console.log(maxExchangeMoney(n));

Output
13
Comment