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], they cannot cast any spell with a damage of power[i] - 2,
power[i] - 1, power[i] + 1, or power[i] + 2.
Each spell can be cast only once.
Return the maximum possible total damage that a magician can cast.
This problem is similar to the “House Robber” or “Delete and Earn” pattern, but with a wider forbidden range. For each unique damage value, if we cast spells of this damage, we must skip all spells with damage within 2 of it. We use dynamic programming to track the best total damage at each value.
classSolution {
publiclongmaximumTotalDamage(int[] power) {
Map<Integer, Integer> freq =new HashMap<>();
for (int x : power) freq.put(x, freq.getOrDefault(x, 0) + 1);
List<Integer> vals =new ArrayList<>(freq.keySet());
Collections.sort(vals);
int n = vals.size();
long[] dp =newlong[n];
for (int i = 0; i < n; ++i) {
long dmg = 1L * vals.get(i) * freq.get(vals.get(i));
int j = i - 1;
while (j >= 0 && vals.get(j) >= vals.get(i) - 2) j--;
long skip = i > 0 ? dp[i-1] : 0L;
long take = dmg + (j >= 0 ? dp[j] : 0L);
dp[i]= Math.max(skip, take);
}
return dp[n-1];
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
classSolution {
funmaximumTotalDamage(power: IntArray): Long {
val freq = mutableMapOf<Int, Int>()
for (x in power) freq[x] = freq.getOrDefault(x, 0) + 1val vals = freq.keys.sorted()
val n = vals.size
val dp = LongArray(n)
for (i in vals.indices) {
val dmg = vals[i].toLong() * freq[vals[i]]!!.toLong()
var j = i - 1while (j >=0&& vals[j] >= vals[i] - 2) j--val skip = if (i > 0) dp[i-1] else0Lval take = dmg + if (j >=0) dp[j] else0L dp[i] = maxOf(skip, take)
}
return dp.last()
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
defmaximumTotalDamage(power: list[int]) -> int:
from collections import Counter
freq = Counter(power)
vals = sorted(freq)
n = len(vals)
dp = [0] * n
for i, v in enumerate(vals):
dmg = v * freq[v]
j = i -1while j >=0and vals[j] >= v -2:
j -=1 skip = dp[i-1] if i >0else0 take = dmg + (dp[j] if j >=0else0)
dp[i] = max(skip, take)
return dp[-1]