Hint
Try finding a total order for the coupons.
Solution
A natural starting point is to try to find a total order for the coupons. This way, we can easily solve the subproblem of checking whether a given subset of coupons is valid by sorting the coupons according to our total order, then simulating.
Define the break-even value of coupon as the unique number such that . If , we set .
Then, we note that if there exists a total ordering, all coupons with the same break-even price should be considered equivalent. For instance, consider several coupons with the same break-even price of : they will all then be of the form , and therefore will always compose into the transformation , no matter how they are ordered. A similar argument holds for other values of .
This motivates a comparator based on , and we can actually show that it’s always optimal to sort in increasing order of . Consider two coupons and with , and a starting value of :
If we put 1 before 2, we effectively only apply 2 (since by definition, 1 leaves an input of unchanged).
However, if we put 2 before 1, we first apply 2, which is guaranteed to decrease since , and then apply 1, which decreases again since now .
Since the slope of the resultant composed coupon is always the same, showing that for a single value of is sufficient to show that holds for all values of .
Now, as long as there exists an with , we can always greedily include it in our subset, so, we now only need to solve the case where all . We can also assume for now that all , since handling is relatively simple.
Under these constraints, we see that the best case (that allows us to take the most coupons) is when all and all . However, even in this best case, it turns out we can only take at most coupons. To see this, we can again consider “shifting our coordinates” such that , like we did when proving that coupons with the same are equivalent. In these shifted coordinates, starts at and becomes after applying coupons.
This allows us to run a simple knapsack dp in .