Maximum Value of K Coins From Piles

Maximum Value of K Coins From Piles

Leetcode Daily Challenge (15th April, 2023)

Problem Statement:-

There are n piles of coins on a table. Each pile consists of a positive number of coins of assorted denominations.

In one move, you can choose any coin on top of any pile, remove it, and add it to your wallet.

Given a list piles, where piles[i] is a list of integers denoting the composition of the i<sup>th</sup> pile from top to bottom, and a positive integer k, return the maximum total value of coins you can have in your wallet if you choose exactly k coins optimally.

Link: https://leetcode.com/problems/maximum-value-of-k-coins-from-piles/description/

Problem Explanation with examples:-

Example 1

Input: piles = [[1,100,3],[7,8,9]], k = 2
Output: 101
Explanation:
The above diagram shows the different ways we can choose k coins.
The maximum total we can obtain is 101.

Example 2

Input: piles = [[100],[100],[100],[100],[100],[100],[1,1,1,1,1,1,700]], k = 7
Output: 706
Explanation:
The maximum total can be obtained if we choose all coins from the last pile.

Constraints

  • n == piles.length

  • 1 <= n <= 1000

  • 1 <= piles[i][j] <= 10<sup>5</sup>

  • 1 <= k <= sum(piles[i].length) <= 2000

Intuition:-

  • Backtracking is the first thing that comes to mind.

  • At each step, we can either take the top of the current pile or move to the next pile and take the top of that pile.

  • We can use memoization to store the results of the subproblems.

  • The changing parameters here are the index of the current pile and the number of coins we have left.

Solution:-

  • Get the length of the piles array and store it in a variable n.

  • Create a recursive function solve(i,coins) which returns the maximum number of coins we can get if we start from the ith pile and have coins coins left.

  • If i >= n, return 0 as we have reached the end of the piles array.

  • Create a variable res and initialize it to the result of the recursive call solve(i+1,coins) which means we are not taking the top of the current pile and moving to the next pile.

  • Create a variable curPile and initialize it to 0.

  • Create a for loop which iterates from 0 to min(coins,len(piles[i])) and in each iteration, we add piles[i][j] to curPile and update res to the maximum of res and curPile + solve(i+1, coins-j-1). Here, we are taking the top j+1 coins from the current pile and moving to the next pile. We are subtracting j+1 from coins as we have taken j+1 coins from the current pile.

  • Return res.

  • Return the result of the recursive call solve(0,k).

Code:-

JAVA Solution

class Solution {
    public int maxValueOfCoins(int[][] piles, int k) {
        int n = piles.length;

        Map<String, Integer> cache = new HashMap<>();

        int res = solve(0, k, piles, n, cache);

        return res;
    }

    public int solve(int i, int coins, int[][] piles, int n, Map<String, Integer> cache) {
        if (i >= n) {
            return 0;
        }

        String key = i + "," + coins;

        if (cache.containsKey(key)) {
            return cache.get(key);
        }

        int res = solve(i + 1, coins, piles, n, cache);
        int curPile = 0;

        for (int j = 0; j < Math.min(coins, piles[i].length); j++) {
            curPile += piles[i][j];
            res = Math.max(res, curPile + solve(i + 1, coins - j - 1, piles, n, cache));
        }

        cache.put(key, res);

        return res;
    }
}

Python Solution

class Solution:
    def maxValueOfCoins(self, piles: List[List[int]], k: int) -> int:
        n = len(piles)
        @cache
        def solve(i,coins):
            if i >= n:
                return 0

            res = solve(i+1,coins)
            curPile = 0
            for j in range(min(coins,len(piles[i]))):
                curPile += piles[i][j]
                res = max(res, curPile + solve(i+1, coins-j-1))
            return res

        return solve(0, k)

Complexity Analysis:-

TIME:-

The time complexity is O(n*k^2), where n is the number of piles and k is the maximum number of coins that can be taken. The recursive function is called for each pile, and in each call, a loop is executed up to k times. Since the function is memoized using a cache, the actual running time will be much lower.

SPACE:-

The space complexity is O(nk) because the cache contains nk entries, one for each unique pair of i and coins. Again, the actual space used will be much lower due to memoization.

References:-

Connect with me:-

Did you find this article valuable?

Support Leeting-LCS by becoming a sponsor. Any amount is appreciated!