Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,28 +1,39 @@
# [3186.Maximum Total Damage With Spell Casting][title]

> [!WARNING|style:flat]
> This question is temporarily unanswered if you have good ideas. Welcome to [Create Pull Request PR](https://github.com/kylesliu/awesome-golang-algorithm)

## Description
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]`, 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.

**Example 1:**

```
Input: a = "11", b = "1"
Output: "100"
```
Input: power = [1,1,3,4]

## 题意
> ...
Output: 6

## 题解
Explanation:

### 思路1
> ...
Maximum Total Damage With Spell Casting
```go
The maximum possible damage of 6 is produced by casting spells 0, 1, 3 with damage 1, 1, 4.
```

**Example 2:**

```
Input: power = [7,1,6,6]

Output: 13

Explanation:

The maximum possible damage of 13 is produced by casting spells 1, 2, 3 with damage 1, 6, 6.
```

## 结语

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,78 @@
package Solution

func Solution(x bool) bool {
return x
import "sort"

func Solution(power []int) int64 {
if len(power) == 0 {
return 0
}

// 1. Calculate Total Damage per Value and collect unique damage values.
damageSums := make(map[int]int64)
for _, p := range power {
damageSums[p] += int64(p)
}

// Get all unique damage values and sort them.
var uniqueDamages []int
for d := range damageSums {
uniqueDamages = append(uniqueDamages, d)
}
sort.Ints(uniqueDamages)

M := len(uniqueDamages)
if M == 0 {
return 0
}

// 2. Dynamic Programming Array F.
// F[i] stores the max total damage considering spells with damage
// up to and including uniqueDamages[i].
F := make([]int64, M)

// F[0] Base Case:
F[0] = damageSums[uniqueDamages[0]]

// 3. DP Iteration:
for i := 1; i < M; i++ {
currentDamage := uniqueDamages[i]
D_i := damageSums[currentDamage]

// Option 1: Skip spells of currentDamage.
// Max damage is F[i-1].
skipDamage := F[i-1]

// Option 2: Cast all spells of currentDamage.
// Gain D_i. Must add to the max damage achieved up to damage currentDamage - 3.

// Find the index 'j' of the *largest* unique damage value <= currentDamage - 3.
// We use sort.Search to find the first element > currentDamage - 3, then step back.

target := currentDamage - 3

// Search for the first index 'k' where uniqueDamages[k] > target.
// Since sort.Search is not available for a custom search over a slice
// and we need to find the index for uniqueDamages, we use sort.SearchInts
// which is equivalent to finding the insertion point.

// 'k' is the index of the first element STRICTLY GREATER THAN target.
k := sort.SearchInts(uniqueDamages, target+1)

// The index of the largest element <= target is k-1.
j := k - 1

var prevMaxDamage int64 // Will be 0 if no such spell exists (j < 0).
if j >= 0 {
// prevMaxDamage is the max damage considering spells up to uniqueDamages[j].
prevMaxDamage = F[j]
}

castDamage := D_i + prevMaxDamage

// F[i] = max(Option 1, Option 2)
F[i] = max(skipDamage, castDamage)
}

// The result is the maximum damage considering all unique damage values.
return F[M-1]
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ func TestSolution(t *testing.T) {
// 测试用例
cases := []struct {
name string
inputs bool
expect bool
inputs []int
expect int64
}{
{"TestCase", true, true},
{"TestCase", true, true},
{"TestCase", false, false},
{"TestCase1", []int{1, 1, 3, 4}, 6},
{"TestCase2", []int{7, 1, 6, 6}, 13},
}

// 开始测试
Expand All @@ -30,10 +29,10 @@ func TestSolution(t *testing.T) {
}
}

// 压力测试
// 压力测试
func BenchmarkSolution(b *testing.B) {
}

// 使用案列
// 使用案列
func ExampleSolution() {
}
Loading