Editorial for CCO '25 P6 - Shopping Deals
Submitting an official solution before solving the problem yourself is a bannable offence.
Author:
Subtask 1
Brute force all possibilities for each shopping deal (assigning it to one of the four regions or leaving it unused).
Time Complexity: .
Subtask 2
Do a bitmask dynamic programming, considering the deals one by one while tracking which subset of the items has been covered by a deal.
Time Complexity: .
Subtask 3
The key observation is that if four shopping deals are chosen, then it is always possible to assign their regions to cover the entire plane. Intuitively, we can assign each deal to a different "quadrant" of the plane. This fact can be verified by brute-forcing all arrangements of four points.
Using this observation, we should either choose the four cheapest shopping deals or brute force all ways to use three or fewer deals, taking
time each to determine which items are covered.
Time Complexity: .
There is a related old math problem asking to prove that for any
points, it is possible to draw a sector with angle
at each point so that the entire plane is covered (one source). The oldest reference appears to be from the Russian journal Kvant: No.11, 1981.
Subtasks 4, 5
The points induce
vertical and
horizontal lines that divide the plane into
rectangular areas, where every possible shopping deal region is a union of some of these areas. Apply coordinate compression to find the sum of the prices of all items in each area, and build a 2D prefix-sum array. Now for each of the
ways to use three or fewer deals, the sum of the prices of all items in the union of the chosen regions can be computed in
time using inclusion-exclusion.
Subtask 4 is created to reward implementations that fail to handle "degenerate" cases correctly, such as by treating the deals as inducing only vertical and
horizontal lines cutting through their coordinates.
Time Complexity: .
Subtasks 6, 7
At a high level, by maintaining some prefix optimum-like quantities, the possible arrangements can all be considered in only
time. The challenge lies in finding an implementation without an unmanageable amount of casework. The author's solution has only
essentially different nontrivial cases.
First, process all ways to use ,
,
, or
shopping deals. There are
essentially different cases for using exactly
shopping deals:
Two of the regions do not intersect at all.
In this case, try all
possibilities for the third deal (
in the above figure). For each possibility, sweep a line (
in the above figure) separating the two remaining regions while maintaining running maximums of the additional savings from
in the first half (i.e., from items not already covered by
), and additional savings from
in the second half.
The opposite "quadrant" of some region is completely uncovered.
In this case, try all possibilities for
, the deal whose opposite region is completely uncovered, as shown in the above figure. For each possibility, calculate the best savings from a deal
within the top-left quadrant of
and the best savings from a deal
within the bottom-right quadrant of
. Since these two quadrants are disjoint, this ensures that no savings are double-counted. Be careful to ensure that
and
are not the same deal (e.g. by also computing second bests).
Only two opposite corners are covered.
In this case, try all possibilities for
, the deal that covers both of the other deals, as shown in the above figure. For each possibility, start by adding in the savings from all items in either the top-right or bottom-left quadrants from
. Take the best savings from a deal
within the top-left quadrant of
and the best savings from a deal
within the bottom-right quadrant of
.
Two deals cover each other and the last deal covers a remaining corner.
In this case, try all combinations for the deals
and
that cover each other, as shown in the above figure. The other deal
should be the minimum cost deal in the top-left quadrant of the point
in the above figure, which can be found using a precomputed 2D prefix minimum array. Be careful to ensure that
,
, and
are all distinct (e.g. by also precomputing second and third bests).
Correctly implementing all of these cases and their rotations/reflections can get full points.
Subtask 6 is created to reward implementations that fail to handle "degenerate" cases correctly.
Time Complexity: .
Comments
So you're claiming that we can always get by with at most 4 deals? This is not true!
Consider the following testcase:
Applying your method described in the subtask 3 an further would give a wrong result,
122
.The correct answer to this testcase is
121
, and this can be confirmed by running the simpler algorithms 1-2.I get
64
for that testcase with several different algorithms.It appears that the cost
of each deal applies to the whole region, not to every individual item within it. It was not clear from the single lean testcase that was provided. I figured it out from my own testcase and your answer on it. Thanks for that.