It is a hidden 01 knapsack problem. The elements are in the stack, which we can only take it one by one from the top, makes it little hard to do the knapsack.
However, we can preprocess the data, making the pile to be a prefix sum pile, which we can get the total coin sum in O(1) time complexity.
After being able to get the taking j element in the stack in O(1), the rest of things are treating k as a weight, and sum of (0 ~ jth element in ith pile) as a value.
we have dp[j] representing the best value of taking j the elements.
the j should start from min( total pile.length() , k ) to 0, here I won't explain why the j should iterate reversely, this is a simple concept of 01 knapsack space compression.
class Solution {
public:
int maxValueOfCoins(vector<vector<int>>& piles, int k) {
int nSum = 0;
int dp[k + 1];
//preprocess
memset(dp, 0, sizeof(dp));
for(auto &pile : piles){
int n = pile.size();
for(int i = 1; i < n; i++){
pile[i] += pile[i - 1];
}
}
for(auto pile : piles){
int n = pile.size();
nSum = min(nSum + n, k);//if the total length<k,you cant take k element
for(int j = nSum; j >= 0; j--){
//try all the new value in new pile to see if there are greater val
for(int k = 0; k < min(n, j); k++){
//pile[0] has 1 weight and pile[1] has 2weights
//so dp[j - (k + 1)]
dp[j] = max(dp[j], dp[j - k - 1] + pile[k]);
}
}
}
return dp[k];
}
};