2023-04-15 Daily Challenge

Today I have done leetcode's April LeetCoding Challenge with cpp.

April LeetCoding Challenge 15

Description

Maximum Value of K Coins From Piles

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 ith 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.

 

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] <= 105
  • 1 <= k <= sum(piles[i].length) <= 2000

Solution

bottom-up approach

class Solution {
public:
  int maxValueOfCoins(vector<vector<int>>& piles, int k) {
    int n = piles.size();
    vector<vector<int>> dp(n + 1, vector<int>(k + 1));

    for(int p = 0; p < n; ++p) {
      dp[p + 1] = dp[p];
      int sum = 0;
      for(int i = 0; i < min<int>(piles[p].size(), k); ++i) {
        sum += piles[p][i];
        for(int j = 0; j + i + 1 <= k; ++j) {
          // cout << p + 1 << ' ' << j + i + 1 <<  ' ' << j << endl;
          dp[p + 1][j + i + 1] = max(dp[p + 1][j + i + 1], dp[p][j] + sum);
        }
        // cout << "OUT!?" << endl;
      }
    }

    return dp[n][k];
  }
};

// Accepted
// 122/122 cases passed (391 ms)
// Your runtime beats 29.06 % of cpp submissions
// Your memory usage beats 65.97 % of cpp submissions (18.1 MB)

top-down approach

auto speedup = [](){
  cin.tie(nullptr);
  cout.tie(nullptr);
  ios::sync_with_stdio(false);
  return 0;
}();
class Solution {
public:
  int maxValueOfCoins(vector<vector<int>>& piles, int k) {
    int n = piles.size();
    for(auto &pile : piles) {
      for(int i = 1; i < pile.size(); ++i) {
        pile[i] += pile[i - 1];
      }
    }
    vector<vector<int>> dp(n, vector<int>(k + 1));

    function<int(int, int)> solve = [&](int pile, int rest) {
      if(!rest || pile == n) return 0;
      if(dp[pile][rest]) return dp[pile][rest];
      int result = solve(pile + 1, rest);
      for(int i = 0; i < piles[pile].size() && i < rest; ++i) {
        result = max(result, piles[pile][i] + solve(pile + 1, rest - i - 1));
      }

      return dp[pile][rest] = result;
    };

    return solve(0, k);
  }
};

// Accepted
// 122/122 cases passed (447 ms)
// Your runtime beats 23.03 % of cpp submissions
// Your memory usage beats 46.34 % of cpp submissions (18.4 MB)