APIO 2009 - Digging for Oil

Author: Albert Ye

APIO 2009 Official Solutions

Explanation

We want the three largest disjoint K×KK \times K squares with the largest total sums. Note that every pair of rectangles must be on opposite sides of some line. This leaves us with two basic configurations; either there are two parallel lines dividing the squares or there are two perpendicular lines. The configurations are illustrated below:

apio09oil fig1

Note that solutions need to account for all possible rotations of these configurations.

Configuration 1

In this configuration, we can find the answer for each non-middle subrectangle using the method in Configuration 2. However, we need to use another recurrence to find the middle rectangle. WLOG let the subrectangles be arranged in top-down order, as the left-right order can be found similarly. Let dpi,jdp_{i, j} be the answer for the rows in interval [i,j][i,j]. Obviously dpi,i+ldp_{i,i+l} has no answers if l<k1l < k-1. We can also manually find dpi,i+kdp_{i, i+k} manually as a base case. Next, note that dpi,jdp_{i,j} consists of all K×KK \times K squares counted in dpi+1,jdp_{i+1, j} and dpi,j1dp_{i, j-1}. Then, there are just the squares counted in row ii and row jj, which is just dpi,i+k1dp_{i, i+k-1} and dpjk+1,jdp_{j-k+1, j} respectively. Thus, the recurrence is dpi,j=max(max(dpi+1,j,dpi,i+k1),max(dpi,j1,dpjk+1,j)).dp_{i,j} = \max(\max(dp_{i+1, j},dp_{i,i+k-1}), \max(dp_{i, j-1}, dp_{j-k+1, j})). Note that intervals must be traversed from smallest to largest.

Configuration 2

It suffices to use prefix sums. From each corner, find the sum of the values of all points that can be reached solely by travelling towards that corner from a point (i,j)(i, j), and store the value with (i,j)(i, j). We can use this to find the total amount of oil for the K×KK \times K squares on each corner of (i,j)(i, j). These values help us find the maximum amount of oil in a K×KK \times K square on each corner of (i,j)(i, j). We then perform some casework for each reflection to get the answer.

Implementation

C++

ppipp_i implements the prefix sum function for each corner, and dpi,jdp_{i,j} is as described.

#include <bits/stdc++.h>
using namespace std;
#define MAXN 1505
int m, n, k, dp[MAXN][MAXN][2], pp[MAXN][MAXN][4], pq[MAXN][MAXN],
ar[MAXN][MAXN];
int main() {
ios_base::sync_with_stdio(0);

Join the USACO Forum!

Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!