Problem Description
Given an integer power and two arrays damage and health of length n, each enemy i deals damage[i] per second to Bob while alive. Every second, after all surviving enemies deal damage, Bob can choose one enemy (that is still alive) to attack and deal power damage to it. Each enemy requires ceil(health[i] / power) attacks (seconds) to be killed. Determine the minimum total damage Bob will receive before all enemies are dead.
Key Insights
- The problem can be modeled as a scheduling problem where each enemy requires a fixed number of rounds (processing time) and has a weight (its damage per second).
- The total damage Bob takes is equivalent to the weighted sum of completion times if you view each enemy as a job.
- To minimize total damage, enemies with a higher “damage rate” relative to the number of rounds required (i.e. a higher ratio of damage[i] to ceil(health[i]/power)) should be targeted first.
- Smith’s rule applies: sort enemies in descending order of damage[i] / rounds (or equivalently, sort by increasing order of rounds[i] / damage[i]) to minimize the weighted sum of completion times.
Space and Time Complexity
Time Complexity: O(n log n) due to sorting the enemies. Space Complexity: O(n) to store the rounds for each enemy and sorting overhead.
Solution
First, compute for each enemy the number of rounds required to kill it using rounds = ceil(health[i] / power) which is implemented as (health[i] + power - 1) // power. Then, using a greedy strategy, sort the enemies using the comparator based on the ratio of damage to rounds. In essence, enemy i should come before enemy j if damage[i] / rounds[i] > damage[j] / rounds[j]. To avoid floating-point calculations, we can compare damage[i] * rounds[j] with damage[j] * rounds[i]. After sorting, simulate the killing process: as you process each enemy in order, maintain the cumulative rounds (which represents the time at which the enemy is killed) and add to the total damage Bob takes the enemy’s damage multiplied by the current cumulative rounds. This computation effectively sums the contribution of each enemy’s damage until it is removed from the battle.