Explanation
Let's consider a case where we have just two cows.
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:
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 and odd .
If 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 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 . To account for this, note that by shifting the ceiling of the data by , we can find the answer for setting all cows to with the same process as earlier.
What information do we have to keep track after processing the first 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 the number of tuples that can be formed if the first elements are set to zero and the th element is hunger value , then this state affects all states such that .
Let's calculate the time complexity!
We'll have number of states, and each transition can take up to operations, so our time complexity would be . Unfortunately, in odd cases, we'll have to try all possible , which'll give us a resulting time complexity of (since all the elements can be the same).
Luckily, because our transition updates a contiguous range of states (), we can process our transition in with a difference array. For example, if we're currently on , our algorithm would manually add to where is within the range . Instead, we'll add to and remember to subtract it at .
This speeds up our algorithm to !
Implementation
Time Complexity:
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!