Taking Maximum Energy From the Mystic Dungeon

medium dynamic programming suffix sum array

Problem

n magicians stand in a line, each with an energy value in energy[i] (possibly negative). After absorbing energy at magician i you are teleported to magician i + k, and you keep going until i + k no longer exists. You pick a starting magician and must absorb every energy along that chain. Return the maximum total energy you can gain over all starting points.

Inputenergy = [5, 2, -10, -5, 1], k = 3
Output3
Starting at index 1 absorbs energy[1] + energy[4] = 2 + 1 = 3, the best of all chains.

def maximumEnergy(energy, k):
    n = len(energy)
    dp = energy[:]              # dp[i] = energy gained starting at i
    best = -10**9
    # fill from the back so dp[i + k] is already complete
    for i in range(n - 1, -1, -1):
        if i + k < n:
            dp[i] += dp[i + k]  # chain on the next teleport
        if dp[i] > best:
            best = dp[i]
    return best
function maximumEnergy(energy, k) {
  const n = energy.length;
  const dp = energy.slice();          // dp[i] = energy gained starting at i
  let best = -Infinity;
  // fill from the back so dp[i + k] is already complete
  for (let i = n - 1; i >= 0; i--) {
    if (i + k < n) {
      dp[i] += dp[i + k];             // chain on the next teleport
    }
    if (dp[i] > best) best = dp[i];
  }
  return best;
}
int maximumEnergy(int[] energy, int k) {
    int n = energy.length;
    int[] dp = energy.clone();          // dp[i] = energy gained starting at i
    int best = Integer.MIN_VALUE;
    // fill from the back so dp[i + k] is already complete
    for (int i = n - 1; i >= 0; i--) {
        if (i + k < n) {
            dp[i] += dp[i + k];         // chain on the next teleport
        }
        if (dp[i] > best) best = dp[i];
    }
    return best;
}
int maximumEnergy(vector<int>& energy, int k) {
    int n = energy.size();
    vector<int> dp = energy;             // dp[i] = energy gained starting at i
    int best = INT_MIN;
    // fill from the back so dp[i + k] is already complete
    for (int i = n - 1; i >= 0; i--) {
        if (i + k < n) {
            dp[i] += dp[i + k];         // chain on the next teleport
        }
        if (dp[i] > best) best = dp[i];
    }
    return best;
}
Time: O(n) Space: O(n)