Video Solution
By Vivian Han
Video Solution Code
Explanation
Suppose that early in the hike, there is a rest stop with tastiness , but later there is a rest stop with tastiness where . Then, it is never optimal for Bessie to spend any time at the first rest stop with tastiness . If she did, she could spend the same amount of time at the later rest stop instead and earn more tastiness units; she would still never be behind Farmer John. So, the only rest stops that Bessie might stop at are those that have more tastiness than any subsequent rest stops.
We can find these "right-maximal" rest stops in a single right-to-left (or end-to-start) scan, keeping track of the largest tastiness seen so far. If the current stop exceeds the largest value seen so far, it is "right-maximal."
Now, we can perform a greedy algorithm: never stop at non-right-maximal rest stops. Bessie should stop at a right-maximal rest stop as long as possible (i.e., until Farmer John catches up with her). Then she proceeds until the next right-maximal rest stop.
To see the correctness of this greedy algorithm, suppose Bessie did not spend as long as possible at some right-maximal rest stop . Then she would leave this rest stop seconds early, for some positive . Suppose the next place Bessie stops is rest stop . We could improve Bessie's tastiness intake by having her spend less second at , and more second at rest stop . It can be verified that Bessie will still never be behind Farmer John, and since the tastiness at is greater than the tastiness at , we improved Bessie's outcome. Therefore no optimal solution will leave a right-maximal rest stop early, and our greedy algorithm is correct.
Implementation
Time Complexity:
C++
#include <fstream>#include <iostream>#include <vector>using namespace std;int main() {ifstream in("reststops.in");int trail_len; // not used
Java
import java.io.*;public class RestStops {public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new FileReader("reststops.in"));String[] line = br.readLine().split(" ");int trailLen = Integer.parseInt(line[0]); // never usedint stopNum = Integer.parseInt(line[1]);int fRate = Integer.parseInt(line[2]);
Python
with open("reststops.in") as read:# trail_len won't be usedtrail_len, stop_num, f_rate, b_rate = [int(i) for i in read.readline().split()]x = [] # position of each stopc = [] # tastiness value of each stopfor _ in range(stop_num):a, b = [int(i) for i in read.readline().split()]x.append(a)c.append(b)
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!