Problem Description
You are given an array power where power[i] is the power required to defeat the iᵗʰ monster. You start with 0 mana and a daily mana gain equal to 1. Every day, you gain mana equal to your current gain. When your accumulated mana reaches or exceeds a monster's power, you can defeat that monster. Defeating a monster resets your mana to 0 and increases your daily gain by 1. The goal is to determine the minimum number of days required to defeat all monsters.
Key Insights
- There are at most 17 monsters, which permits using a bitmask dynamic programming (DP) solution that iterates over all subsets.
- The order in which you defeat monsters is crucial; one effective strategy is to decide which monster to kill next given your current mana gain (which equals the number of monsters defeated so far plus one).
- The days needed to defeat a monster with power P when your gain is g is computed as ceil(P / g). This represents waiting enough days until your accumulated mana becomes sufficient.
- The DP state uses a bitmask where each bit indicates whether a monster has been defeated. The current gain is deduced from the number of defeated monsters.
- Transition between states: from a state represented by mask and with current gain = (popcount(mask) + 1) try defeating any remaining monster and update the days accordingly.
Space and Time Complexity
Time Complexity: O(2ⁿ * n), where n is the number of monsters.
Space Complexity: O(2ⁿ), required for storing the DP state for each subset of monsters.
Solution
We use a bitmask dynamic programming approach where each state is represented by a bitmask, indicating which monsters have been defeated.
- Define dp[mask] as the minimum number of days needed to defeat the monsters in the set represented by mask.
- The starting condition is dp[0] = 0 (no monsters defeated, 0 days used).
- For each dp[mask], determine the current gain g = count of defeated monsters + 1.
- For each monster not yet defeated (i.e., corresponding bit is 0 in mask), calculate the minimum days needed to accumulate enough mana: days_needed = ceil(power[i] / g).
- Transition to the new state (i.e., new_mask = mask OR (1 << i)) with dp[new_mask] = min(dp[new_mask], dp[mask] + days_needed).
- The answer is dp[(1 << n) - 1], where all monsters have been defeated.
The challenge involves correctly computing the ceiling of the division and updating the DP states optimally.