<p>A magician has various spells.</p>

<p>You are given an array <code>power</code>, where each element represents the damage of a spell. Multiple spells can have the same damage value.</p>

<p>It is a known fact that if a magician decides to cast a spell with a damage of <code>power[i]</code>, they <strong>cannot</strong> cast any spell with a damage of <code>power[i] - 2</code>, <code>power[i] - 1</code>, <code>power[i] + 1</code>, or <code>power[i] + 2</code>.</p>

<p>Each spell can be cast <strong>only once</strong>.</p>

<p>Return the <strong>maximum</strong> possible <em>total damage</em> that a magician can cast.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">power = [1,1,3,4]</span></p>

<p><strong>Output:</strong> <span class="example-io">6</span></p>

<p><strong>Explanation:</strong></p>

<p>The maximum possible damage of 6 is produced by casting spells 0, 1, 3 with damage 1, 1, 4.</p>
</div>

<p><strong class="example">Example 2:</strong></p>

<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">power = [7,1,6,6]</span></p>

<p><strong>Output:</strong> <span class="example-io">13</span></p>

<p><strong>Explanation:</strong></p>

<p>The maximum possible damage of 13 is produced by casting spells 1, 2, 3 with damage 1, 6, 6.</p>
</div>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= power.length &lt;= 10<sup>5</sup></code></li>
	<li><code>1 &lt;= power[i] &lt;= 10<sup>9</sup></code></li>
</ul>

import numpy as np
class Solution:
    def maximumTotalDamage(self, power: List[int]) -> int:
        lst = sorted(power)
        unique = {}
        for i in lst:
            if i in unique:
                unique[i] += 1
            else:
                unique[i]=1

        nums = list(unique.keys())
        poids = list(unique.values())
       

        dp = [[0,0] for i in range(len(nums))]

        #first value 
        dp[0][0] = nums[0]*poids[0]
        dp[0][1] = 0
        if len(nums)==1:
            return dp[0][0]
        
        dp[1][0] = nums[1]*poids[1] + dp[0][0] if nums[0]<nums[1]-2 else nums[1]*poids[1]
        dp[1][1] = dp[0][0]
        
        if len(nums)==2:
            return max(dp[1][1],dp[1][0])
        #second value 
        if nums[1]<nums[2]-2:
            dp[2][0] = nums[2]*poids[2] + max(dp[1][0],dp[1][1])
            

        elif nums[1] == nums[2]-1 and nums[0] == nums[2]-2:
            dp[2][0] = nums[2]*poids[2] 
          
        elif nums[1] == nums[2]-1 and nums[0]<nums[2]-2:
            dp[2][0] =  nums[2]*poids[2]  + max(dp[0][0],dp[0][1])
     
        else:
            dp[2][0] = nums[2]*poids[2] + max(dp[0][0],dp[0][1]) #nums[i-1]==nums[i]-2

            
        dp[2][1] = max(dp[1][0],dp[1][1])
        
        if len(nums)==3:
            return max(dp[2][0],dp[2][1])


        for i in range(3,len(nums)):
            if nums[i-1]<nums[i]-2:
                dp[i][0] = nums[i]*poids[i] + max(dp[i-1][0],dp[i-1][1])

            elif nums[i-1] == nums[i]-1 and nums[i-2] == nums[i]-2:
                dp[i][0] = nums[i]*poids[i] + max(dp[i-3][0],dp[i-3][1])

            elif nums[i-1] == nums[i]-1 and nums[i-2]<nums[i]-2:
                dp[i][0] =  nums[i]*poids[i] + max(dp[i-2][0],dp[i-2][1])
            else:
                dp[i][0] = nums[i]*poids[i] + max(dp[i-2][0],dp[i-2][1]) #nums[i-1]==nums[i]-2
            
            dp[i][1] = max(dp[i-1][0],dp[i-1][1])
       
        return max(dp[len(nums)-1][0],dp[len(nums)-1][1])

      


            
        
56293