Table of Contents

ExplanationImplementation

Official Analysis (C++)

Alternative Analysis (C++)

Explanation

Let's consider a case where we have just two cows.

[2,2][2, 2]

In any case where the two hunger values are equal, it's always possible to reduce them both to zero! (by decreasing adjacent elements).

However, with three cows:

[2,2,2][2, 2, 2]

We can't apply the same transformation. In fact, for any odd number of cows, it's impossible to guarantee that we can decrement all the elements to zero even if all the elements are equal.

This motivates us to split the problem into two cases: even NN and odd NN.

If NN is even, then we can count the number of tuples such that all the elements are at zero because we can guarantee that this tuple can reach all equal states and vice versa.

However, if NN is odd, we can't make the same assumption, they could be equal at any value! Thus, we have to count the number of tuples for all possible hunger levels xx. To account for this, note that by shifting the ceiling of the data by xx, we can find the answer for setting all cows to xx with the same process as earlier.

What information do we have to keep track after processing the first ii cows?

While it may seem that the index is all we need, since we can only decrease the right-most cow with the one to the left of it, we also have to keep track of the current cow's hunger value such that we don't make it impossible to get the right-most cow to zero.

More formally, if we let dp[i][j]=\texttt{dp}[i][j] = the number of tuples that can be formed if the first i1i - 1 elements are set to zero and the iith element is hunger value jj, then this state affects all states dp[i+1][khi]\texttt{dp}[i + 1][k - h_i] such that hikhi+1h_i \leq k \leq h_{i + 1}.

Let's calculate the time complexity!

We'll have NmaxHN \cdot \max H number of states, and each transition can take up to maxH\max H operations, so our time complexity would be O(N(maxH)2)\mathcal{O}(N(\max H)^2). Unfortunately, in odd cases, we'll have to try all possible x<minHx < \min H, which'll give us a resulting time complexity of O(N(maxH)3)\mathcal{O}(N(\max H)^3) (since all the elements can be the same).

Luckily, because our transition updates a contiguous range of states ([0,hi][0, h_i]), we can process our transition in O(1)\mathcal{O}(1) with a difference array. For example, if we're currently on dp[i][j]\texttt{dp}[i][j], our algorithm would manually add dp[i][j]\texttt{dp}[i][j] to dp[i+1][k]\texttt{dp}[i + 1][k] where kk is within the range [0,hi][0, h_i]. Instead, we'll add dp[i][j]\texttt{dp}[i][j] to diff[0]\texttt{diff}[0] and remember to subtract it at diff[hi]\texttt{diff}[h_i].

This speeds up our algorithm to O(N(maxH)2)\mathcal{O}(N(\max H)^2)!

Implementation

Time Complexity: O(N(maxH)2)\mathcal{O}(N(\max H)^2)

C++

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MOD = 1e9 + 7;
const int MX_HUNGER = 1000;
int 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!