Watch 2 video solutions for Minimum Time to Kill All Monsters, a hard level problem involving Array, Dynamic Programming, Bit Manipulation. This walkthrough by Huifeng Guan has 219 views views. Want to try solving it yourself? Practice on FleetCode or read the detailed text solution.
You are given an integer array power where power[i] is the power of the ith monster.
You start with 0 mana points, and each day you increase your mana points by gain where gain initially is equal to 1.
Each day, after gaining gain mana, you can defeat a monster if your mana points are greater than or equal to the power of that monster. When you defeat a monster:
0, andgain increases by 1.Return the minimum number of days needed to defeat all the monsters.
Example 1:
Input: power = [3,1,4] Output: 4 Explanation: The optimal way to beat all the monsters is to: - Day 1: Gain 1 mana point to get a total of 1 mana point. Spend all mana points to kill the 2nd monster. - Day 2: Gain 2 mana points to get a total of 2 mana points. - Day 3: Gain 2 mana points to get a total of 4 mana points. Spend all mana points to kill the 3rd monster. - Day 4: Gain 3 mana points to get a total of 3 mana points. Spend all mana points to kill the 1st monster. It can be proven that 4 is the minimum number of days needed.
Example 2:
Input: power = [1,1,4] Output: 4 Explanation: The optimal way to beat all the monsters is to: - Day 1: Gain 1 mana point to get a total of 1 mana point. Spend all mana points to kill the 1st monster. - Day 2: Gain 2 mana points to get a total of 2 mana points. Spend all mana points to kill the 2nd monster. - Day 3: Gain 3 mana points to get a total of 3 mana points. - Day 4: Gain 3 mana points to get a total of 6 mana points. Spend all mana points to kill the 3rd monster. It can be proven that 4 is the minimum number of days needed.
Example 3:
Input: power = [1,2,4,9] Output: 6 Explanation: The optimal way to beat all the monsters is to: - Day 1: Gain 1 mana point to get a total of 1 mana point. Spend all mana points to kill the 1st monster. - Day 2: Gain 2 mana points to get a total of 2 mana points. Spend all mana points to kill the 2nd monster. - Day 3: Gain 3 mana points to get a total of 3 mana points. - Day 4: Gain 3 mana points to get a total of 6 mana points. - Day 5: Gain 3 mana points to get a total of 9 mana points. Spend all mana points to kill the 4th monster. - Day 6: Gain 4 mana points to get a total of 4 mana points. Spend all mana points to kill the 3rd monster. It can be proven that 6 is the minimum number of days needed.
Constraints:
1 <= power.length <= 171 <= power[i] <= 109Problem Overview: You are given an array where power[i] represents the strength of the i-th monster. Your weapon starts with power 1 and increases by 1 after every kill. Killing a monster with weapon power x takes ceil(power[i] / x) time. The order of kills changes the total time, so the task is to find the order that minimizes the total time needed to defeat all monsters.
Approach 1: State Compression + Memoization Search (O(n * 2^n) time, O(2^n) space)
The key observation: the only thing that matters at any moment is which monsters have already been killed. Represent this state using a bitmask where bit i indicates whether monster i is defeated. The number of killed monsters k determines the current weapon power (k + 1). Use depth‑first search with memoization: from a given mask, try killing every remaining monster. For each candidate i, compute the time ceil(power[i] / (k + 1)), then recurse on the new mask. Memoize results for each mask to avoid recomputing overlapping states. This is a classic bitmask state search where each state branches to remaining monsters. With memoization, every mask is evaluated once and transitions try up to n monsters.
Approach 2: State Compression + Dynamic Programming (O(n * 2^n) time, O(2^n) space)
This approach converts the recursive idea into bottom‑up dynamic programming. Let dp[mask] store the minimum time required to defeat the set of monsters represented by mask. The number of set bits k determines the weapon power when the next monster is attacked: k monsters already killed means the next attack uses power k. For each mask, iterate through monsters not yet killed and update the next state: nextMask = mask | (1 << i). The transition cost is ceil(power[i] / k) where k = popcount(mask) + 1. Update dp[nextMask] with the minimum possible time. Iterate masks from small to large so previous states are already computed. The final answer is dp[(1 << n) - 1], meaning all monsters are defeated.
The bitmask representation is what makes the problem tractable. Without it, enumerating all permutations would require O(n!) time. State compression reduces the search to 2^n states while still capturing the effect of order through the increasing weapon power.
Recommended for interviews: The state compression dynamic programming solution is typically expected. It shows you recognize permutation-style optimization problems and convert them into 2^n DP states. Mentioning the DFS + memoization variant demonstrates understanding of the same state transition from a top‑down perspective, while the bottom‑up DP implementation highlights mastery of bitmask DP patterns frequently asked in hard interview problems.
| Approach | Time | Space | When to Use |
|---|---|---|---|
| State Compression + Memoization Search | O(n * 2^n) | O(2^n) | Good when reasoning about the problem recursively and exploring monster orders via DFS. |
| State Compression + Dynamic Programming | O(n * 2^n) | O(2^n) | Preferred for interviews and production solutions when n ≤ 17 and you want deterministic bottom‑up computation. |