2
2
id : usaco-923
3
3
source : USACO Gold 2019 February
4
4
title : Painting the Barn
5
- author : Kevin Sheng
5
+ author : Kevin Sheng, KJ Karaisz
6
6
---
7
7
8
+ <Warning title = " Prior Knowledge" >
9
+
10
+ This editorial assumes one already has a firm grasp of the
11
+ [ silver] ( http://www.usaco.org/current/data/sol_paintbarn_silver_feb19.html )
12
+ version of this problem.
13
+
14
+ </Warning >
15
+
16
+ <Spoiler title = " Hint 1" >
17
+
18
+ Say FJ could only paint one rectangle of paint over the barn.
19
+ Then, this problem would turn into finding the
20
+ [ maximum sum of a submatrix] ( https://stackoverflow.com/a/18220549/12128483 ) .
21
+
22
+ </Spoiler >
23
+
24
+ <Spoiler title = " Hint 2" >
25
+
26
+ So you have your one rectangle now. How do you make this algorithm work for two?
27
+
28
+ Try to think about how you can guarantee disjoint rectangles!
29
+
30
+ </Spoiler >
31
+
32
+ <Spoiler title = " Answer to Hint 2" >
33
+
34
+ If two rectangles are disjoint, there can always be a horizontal or vertical line separating them.
35
+
36
+ </Spoiler >
37
+
38
+ <Spoiler title = " Solution" >
39
+
8
40
[ Official Analysis (C++)] ( http://www.usaco.org/current/data/sol_paintbarn_gold_feb19.html )
9
41
10
42
## Explanation
11
43
12
44
### Initial Observations
13
45
14
- ** Note:** This solution assumes one has already had a firm grasp of the
15
- [ silver] ( http://www.usaco.org/current/data/sol_paintbarn_silver_feb19.html )
16
- version of this problem.
17
-
18
46
We start off by calculating the layers of paint over each cell of the barn with
19
47
prefix sums, but from there it's a bit hard to determine which layers we should
20
- paint. It's hard to directly calculate it from this array, but notice that there's
21
- two general states a cell can be in.
48
+ paint. It's hard to directly calculate it from this array, but notice that
49
+ there's two general states a cell can be in.
22
50
23
- 1 . If it's painted over, it will either add $1$ to the optimal area
24
- (because it initially has $K-1$ layers of paint)
25
- or subtract $1$ from the optimal area
51
+ 1 . If it's painted over, it will either add $1$ to the optimal area (because it
52
+ initially has $K-1$ layers of paint) or subtract $1$ from the optimal area
26
53
(because it already has $K$ layers of paint).
27
- 3 . Nothing will happen to the optimal area if it's painted over.
54
+ 2 . Nothing will happen to the optimal area if it's painted over.
28
55
29
- Since FJ must paint two * disjoint * rectangles, we don't have to consider the
56
+ Since FJ must paint two _ disjoint _ rectangles, we don't have to consider the
30
57
cells that need two layers of paint to become optimal.
31
58
32
59
Let's call this array $\texttt{ leftovers } $. With our example input, it would
@@ -52,14 +79,15 @@ $200\times200$ matrix):
52
79
### Using Kadane's
53
80
54
81
Now, we've reduced this problem to finding the max submatrix sum on a matrix,
55
- given that we can have two disjoint submatrices.
56
- Though it's a tall talk, let's try and tackle this bit by bit, first by considering
57
- if there's only * 1 * matrix we can paint.
82
+ given that we can have two disjoint submatrices. Though it's a tall task, let's
83
+ try and tackle this bit by bit, first by considering if there's only _ 1 _ matrix
84
+ we can paint.
58
85
59
86
To do that, we use a 2D version of
60
87
[ Kadane's Algorithm] ( https://en.wikipedia.org/wiki/Maximum_subarray_problem#Kadane's_algorithm ) .
61
88
62
89
The $\mathcal{ O } (N)$ 1D version can be implemented by the following code:
90
+
63
91
<LanguageSection >
64
92
<CPPSection >
65
93
@@ -106,49 +134,58 @@ def max_subarray(arr: List[int]) -> int:
106
134
</PySection >
107
135
</LanguageSection >
108
136
109
- We can extend this to the second dimension
110
- (albeit with an extra $N^2$ factor in the complexity)
111
- by iterating through all ranges of columns in the matrix and running a 1D Kadane's
112
- where the sum of each element is the subarray is the sum of the column range of a row.
137
+ We can extend this to the second dimension (albeit with an extra $N^2$ factor in
138
+ the complexity) by iterating through all ranges of columns in the matrix and
139
+ running a 1D Kadane's where the sum of each element is the subarray is the sum
140
+ of the column range of a row.
141
+
142
+ For example, if our current column range was $[ 0,2] $, then we'd run our 1D
143
+ Kadane's on the following array:
113
144
114
- For example, if our current column range was $[ 0,2] $, then we'd run our 1D Kadane's
115
- on the following array:
116
145
$$
117
146
[0,2,0,0,1,1,1,0,0,0]
118
147
$$
119
148
120
149
### Solving the Second Matrix
121
150
122
151
The key to getting the max with two submatrices is noticing that there will
123
- always be a line, vertical or horizontal, that can divide the grid such that
124
- one rectangle is in one section and the other rectangle is in the other section.
152
+ always be a line, vertical or horizontal, that can divide the grid such that one
153
+ rectangle is in one section and the other rectangle is in the other section.
125
154
126
155
Building on this observation, we can go through all the lines we can draw
127
- through the matrix and get the max subarray on both sides.
128
- After this, we can take the max of the results of these lines and add it
129
- to the number of cells that were initially painted with the optimal number
130
- of layers of paint to get our final answer.
156
+ through the matrix and get the max subarray on both sides. After this, we can
157
+ take the max of the results of these lines and add it to the number of cells
158
+ that were initially painted with the optimal number of layers of paint to get
159
+ our final answer.
131
160
132
161
We need a method to efficiently calculate the max submatrices for all the split
133
- regions, though.
134
- To start off, let's define four arrays which will have the following
135
- *** initial*** values:
136
-
137
- * $\texttt{ top \_best [i ]} $: the best matrix whose *** lower*** side is the $i$th row.
138
- * $\texttt{ bottom \_best [i ]} $: the best matrix whose *** upper*** side is the $i$th row.
139
- * $\texttt{ left \_best [i ]} $: the best matrix whose *** right*** side is the $i$th column.
140
- * $\texttt{ right \_best [i ]} $: the best matrix whose *** left*** side is the $i$th column.
162
+ regions, though. To start off, let's define four arrays which will have the
163
+ following ** _ initial_ ** values:
164
+
165
+ - $\texttt{ top \_best [i ]} $: the best matrix whose ** _ lower_ ** side is the $i$th
166
+ row.
167
+ - $\texttt{ bottom \_best [i ]} $: the best matrix whose ** _ upper_ ** side is the
168
+ $i$th row.
169
+ - $\texttt{ left \_best [i ]} $: the best matrix whose ** _ right_ ** side is the $i$th
170
+ column.
171
+ - $\texttt{ right \_best [i ]} $: the best matrix whose ** _ left_ ** side is the $i$th
172
+ column.
141
173
142
174
We fill these arrays by running a 2D Kadane's starting from the top, bottom,
143
- left, or right, and updating the corresponding arrays with the max submatrix value.
175
+ left, or right, and updating the corresponding arrays with the max submatrix
176
+ value.
144
177
145
- Next, we do a cumulative maximum from the start or from the end depending on the array
146
- to get the arrays with the following updated values:
178
+ Next, we do a cumulative maximum from the start or from the end depending on the
179
+ array to get the arrays with the following updated values:
147
180
148
- * $\texttt{ top \_best [i ]} $: the best matrix that lies *** at or above*** the $i$th row.
149
- * $\texttt{ bottom \_best [i ]} $: the best matrix that lies *** at or below*** $i$th row.
150
- * $\texttt{ left \_best [i ]} $: the best matrix that's *** at or to the left of*** the $i$th column.
151
- * $\texttt{ right \_best [i ]} $: the best matrix that's *** at or to the right of*** the $i$th column.
181
+ - $\texttt{ top \_best [i ]} $: the best matrix that lies ** _ at or above_ ** the $i$th
182
+ row.
183
+ - $\texttt{ bottom \_best [i ]} $: the best matrix that lies ** _ at or below_ ** $i$th
184
+ row.
185
+ - $\texttt{ left \_best [i ]} $: the best matrix that's ** _ at or to the left of_ **
186
+ the $i$th column.
187
+ - $\texttt{ right \_best [i ]} $: the best matrix that's ** _ at or to the right of_ **
188
+ the $i$th column.
152
189
153
190
## Implementation
154
191
@@ -407,3 +444,4 @@ public final class PaintBarn {
407
444
408
445
</JavaSection>
409
446
</LanguageSection>
447
+ </Spoiler>
0 commit comments