Skip to content

Instantly share code, notes, and snippets.

@tatsuyax25
Created October 11, 2025 16:57
Show Gist options
  • Select an option

  • Save tatsuyax25/9951cf0dbb4ae6b8adde25fa544db5e7 to your computer and use it in GitHub Desktop.

Select an option

Save tatsuyax25/9951cf0dbb4ae6b8adde25fa544db5e7 to your computer and use it in GitHub Desktop.
A magician has various spells. You are given an array power, where each element represents the damage of a spell. Multiple spells can have the same damage value. It is a known fact that if a magician decides to cast a spell with a damage of power[i
/**
* @param {number[]} power
* @return {number}
*/
var maximumTotalDamage = function(power) {
// Step 1: Count how many times each damage value appears
const count = new Map();
for (const dmg of power) {
count.set(dmg, (count.get(dmg) || 0) + 1);
}
// Step 2: Sort unique damage values in ascending order
const unique = Array.from(count.keys()).sort((a, b) => a - b);
const n = unique.length;
// Edge case: only one unique damage value
if (n === 1) {
return unique[0] * count.get(unique[0]);
}
// Step 3: Initialize DP array
// dp[i] stores the max damage using the first i unique damage values
const dp = new Array(n + 1).fill(0);
dp[0] = 0;
dp[1] = unique[0] * count.get(unique[0]);
// Step 4: Handle second damage value with conflict check
if (unique[1] - unique[0] > 2) {
// No conflict: safe to add both
dp[2] = dp[1] + unique[1] * count.get(unique[1]);
} else {
// Conflict: choose max of taking current or skipping it
dp[2] = Math.max(dp[1], unique[1] * count.get(unique[1]));
}
// Step 5: Fill DP table for remaining values
for (let i = 3; i <= n; i++) {
const curr = unique[i - 1];
const prev1 = unique[i - 2];
const prev2 = unique[i - 3];
const currTotal = curr * count.get(curr);
if ((curr - prev1 > 2) && (curr - prev2 > 2)) {
// No conflict with previous two: safe to add
dp[i] = dp[i - 1] + currTotal;
} else if ((curr - prev2 > 2) && (curr - prev1 <= 2)) {
// Conflict with prev1 only: choose max of skipping or taking with dp[i-2]
dp[i] = Math.max(dp[i - 2] + currTotal, dp[i - 1]);
} else {
// Conflict with both prev1 and prev2: choose max of skipping or taking with dp[i-3]
dp[i] = Math.max(dp[i - 3] + currTotal, dp[i - 1]);
}
}
// Final result: max damage using all unique values
return dp[n];
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment