Official Analysis

Explanation

Note that since it might not always be optimal to keep the strongest/heaviest cow at the bottom of the stack, we have to go through every single possible subset, which is feasible with N20N \leq 20.

Here's an example of a counter case:

4 6
1 1000 4
1 1 5
3 2 3
3 3 3

(In this case, it's more optimal to take the last two cows instead!)

Almost every time the bounds are ~2020, it suggests looping over subsets.

Let's go through the information we need to implement it!

States

Let's use a bitmask (mask\texttt{mask}) to keep track of the cows we're using.

To check if we've surpassed Mark's height already and if so, return the result, we should also keep track of the current height and the best safety factor we can get.

dp[mask]={\texttt{dp}[\texttt{mask}] =\{current height, maximum safety factor achievable}\}

Base Case

With no cows, the safety factor will be infinite and the height will be zero.

Transitions

dp[mask]=maxjmask(dp[mask],min(dp[mask\j]weightj,strengthj))\texttt{dp}[\texttt{mask}] = \max_{j \in mask}(\texttt{dp}[\texttt{mask}],\hspace{0.1cm}\min(\texttt{dp}[\texttt{mask} \char`\\ j] - \texttt{weight}_j,\hspace{0.1cm}\texttt{strength}_j))

Such that jj is the index of the jjth cow and weightj,strengthj\texttt{weight}_j,\hspace{0.1cm}\texttt{strength}_j represents the weight and strength of cow jj respectively.

This gets the maximum safety factor if we put cow jj at the top of our stack for every jj. We have to take into account strengthj\texttt{strength}_j and dp[mask\j]weightj\texttt{dp}[\texttt{mask} \char`\\ j] - \texttt{weight}_j in the case that either one of the cows below can't sustain as much weight as cow jj can, or vice-versa.

Implementation

Time Complexity: O(2NN)\mathcal{O}(2^N \cdot N)

C++

#include <bits/stdc++.h>
using namespace std;
struct Cow {
int height;
int weight;
int strength;
};
int main() {

Java

import java.io.*;
import java.util.*;
public class GuardMark {
public static void main(String[] args) throws IOException {
Kattio io = new Kattio("guard");
int N = io.nextInt();
int H = io.nextInt();
Cow[] cows = new Cow[N];

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!