APIO 2014 - Sequence
Author: Andi Qu
Intuition
After playing around with some arrays, you will probably find that the order of splits doesn't matter.
Why is this true?
Consider the case where . Let the 3 arrays have sums , , and . If you split into and then , then you get points. If you split the array into and then though, you still get points.
A similar argument holds for .
We have now greatly simplified our problem! Without loss of generality, assume we make splits from left to right.
Formulating a DP
First, let be the sum of for all .
Let be the maximum number of points we can get if we have made splits and the -th split is between and .
We have the following recurrence:
The answer is (assuming we make an extra split at the end of the array, which doesn't affect our answer).
Computing this naively would take time, but we can do much better than that.
Using CHT
Look at the DP recurrence again. Can you see how it's effectively finding the maximum of several linear functions at a point?
We can rearrange the recurrence to become
Recall that a linear function can be defined as .
In this case, we have , , and .
This means we can use CHT (with a deque) to compute the answer in - a significant improvement!
One Final Optimization
Unfortunately, if we implement this solution directly, we exceed the memory limits.
Notice how only depends on . This means that instead of storing arrays of , we can simply store two arrays and alternate between them.
This brings the memory used down to , which is good enough to pass.
Complexity
Time: .
Memory: .
Code
1#include <bits/stdc++.h>2#pragma GCC optimize("O3")3#define FOR(i, x, y) for (int i = x; i < y; i++)4typedef long long ll;5using namespace std;67int n, k;8int where[201][100001];9ll pref[100001]{0}, dp[2][100001], q[100001], l = 1, r = 1;10
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!