diff --git a/leetcode/3401-3500/3494.Find-the-Minimum-Amount-of-Time-to-Brew-Potions/1.png b/leetcode/3401-3500/3494.Find-the-Minimum-Amount-of-Time-to-Brew-Potions/1.png new file mode 100644 index 000000000..c30d4909f Binary files /dev/null and b/leetcode/3401-3500/3494.Find-the-Minimum-Amount-of-Time-to-Brew-Potions/1.png differ diff --git a/leetcode/3401-3500/3494.Find-the-Minimum-Amount-of-Time-to-Brew-Potions/README.md b/leetcode/3401-3500/3494.Find-the-Minimum-Amount-of-Time-to-Brew-Potions/README.md index 8ce3f8c87..263a9a840 100755 --- a/leetcode/3401-3500/3494.Find-the-Minimum-Amount-of-Time-to-Brew-Potions/README.md +++ b/leetcode/3401-3500/3494.Find-the-Minimum-Amount-of-Time-to-Brew-Potions/README.md @@ -1,28 +1,49 @@ # [3494.Find the Minimum Amount of Time to Brew Potions][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 +You are given two integer arrays, `skill` and `mana`, of length `n` and `m`, respectively. + +In a laboratory, `n` wizards must brew `m` potions in order. Each potion has a mana capacity `mana[j]` and **must** pass through **all** the wizards sequentially to be brewed properly. The time taken by the `ith` wizard on the `jth` potion is `timeij = skill[i] * mana[j]`. + +Since the brewing process is delicate, a potion **must** be passed to the next wizard immediately after the current wizard completes their work. This means the timing must be synchronized so that each wizard begins working on a potion **exactly** when it arrives. + +Return the **minimum** amount of time required for the potions to be brewed properly. -**Example 1:** +**Example 1:** + +![1](./1.png) ``` -Input: a = "11", b = "1" -Output: "100" +Input: skill = [1,5,2,4], mana = [5,1,4,2] + +Output: 110 + +Explanation: + +As an example for why wizard 0 cannot start working on the 1st potion before time t = 52, consider the case where the wizards started preparing the 1st potion at time t = 50. At time t = 58, wizard 2 is done with the 1st potion, but wizard 3 will still be working on the 0th potion till time t = 60. ``` -## 题意 -> ... +**Exmaple 2:** -## 题解 +``` +Input: skill = [1,1,1], mana = [1,1,1] + +Output: 5 -### 思路1 -> ... -Find the Minimum Amount of Time to Brew Potions -```go +Explanation: + +Preparation of the 0th potion begins at time t = 0, and is completed by time t = 3. +Preparation of the 1st potion begins at time t = 1, and is completed by time t = 4. +Preparation of the 2nd potion begins at time t = 2, and is completed by time t = 5. ``` +**Example 3:** + +``` +Input: skill = [1,2,3,4], mana = [1,2] + +Output: 21 +``` ## 结语 diff --git a/leetcode/3401-3500/3494.Find-the-Minimum-Amount-of-Time-to-Brew-Potions/Solution.go b/leetcode/3401-3500/3494.Find-the-Minimum-Amount-of-Time-to-Brew-Potions/Solution.go index d115ccf5e..809ea5ab9 100644 --- a/leetcode/3401-3500/3494.Find-the-Minimum-Amount-of-Time-to-Brew-Potions/Solution.go +++ b/leetcode/3401-3500/3494.Find-the-Minimum-Amount-of-Time-to-Brew-Potions/Solution.go @@ -1,5 +1,42 @@ package Solution -func Solution(x bool) bool { - return x +func Solution(skill []int, mana []int) int64 { + N, M := len(skill), len(mana) + prevPotion := make([]int64, N) + for potion := 0; potion < M; potion++ { + var startTime int64 + if potion > 0 { + // Need to find the min time in between these two to start + start, end := prevPotion[0], prevPotion[N-1] + for start <= end { + mid := start + (end-start)/2 + if canCompletePotion(mid, potion, prevPotion, skill, mana) { + startTime = mid + end = mid - 1 + } else { + start = mid + 1 + } + } + } + for wiz := 0; wiz < N; wiz++ { + prevPotion[wiz] = startTime + int64(skill[wiz])*int64(mana[potion]) + startTime = prevPotion[wiz] + } + } + return prevPotion[N-1] +} + +func canCompletePotion(startTime int64, potionCount int, prevPotion []int64, skill, mana []int) bool { + for wizard := 0; wizard < len(skill); wizard++ { + doneTime := startTime + int64(skill[wizard])*int64(mana[potionCount]) + // If the done time for the previous potion is greater than this one + // it means we cannot hand off this potion to the next wizard in a sequential + // manner. + if prevPotion[wizard] > startTime { + return false + } + startTime = doneTime + } + // As long as all potions are done after the previous, we are ok. + return true } diff --git a/leetcode/3401-3500/3494.Find-the-Minimum-Amount-of-Time-to-Brew-Potions/Solution_test.go b/leetcode/3401-3500/3494.Find-the-Minimum-Amount-of-Time-to-Brew-Potions/Solution_test.go index 14ff50eb4..b693c936c 100644 --- a/leetcode/3401-3500/3494.Find-the-Minimum-Amount-of-Time-to-Brew-Potions/Solution_test.go +++ b/leetcode/3401-3500/3494.Find-the-Minimum-Amount-of-Time-to-Brew-Potions/Solution_test.go @@ -9,31 +9,31 @@ import ( func TestSolution(t *testing.T) { // 测试用例 cases := []struct { - name string - inputs bool - expect bool + name string + skill, mana []int + expect int64 }{ - {"TestCase", true, true}, - {"TestCase", true, true}, - {"TestCase", false, false}, + {"TestCase1", []int{1, 5, 2, 4}, []int{5, 1, 4, 2}, 110}, + {"TestCase2", []int{1, 1, 1}, []int{1, 1, 1}, 5}, + {"TestCase3", []int{1, 2, 3, 4}, []int{1, 2}, 21}, } // 开始测试 for i, c := range cases { t.Run(c.name+" "+strconv.Itoa(i), func(t *testing.T) { - got := Solution(c.inputs) + got := Solution(c.skill, c.mana) if !reflect.DeepEqual(got, c.expect) { - t.Fatalf("expected: %v, but got: %v, with inputs: %v", - c.expect, got, c.inputs) + t.Fatalf("expected: %v, but got: %v, with inputs: %v %v", + c.expect, got, c.skill, c.mana) } }) } } -// 压力测试 +// 压力测试 func BenchmarkSolution(b *testing.B) { } -// 使用案列 +// 使用案列 func ExampleSolution() { }