Moo Route
Pista 1
Intentemos visualizar los caminos así:

Pista 2
Consideremos construir una solución de forma recursiva. Si construimos un camino que satisface las restricciones , ¿cómo obtenemos un camino que satisface ?
Solución
Consideremos construir una solución de forma recursiva. Si construimos un camino que satisface las restricciones , ¿cómo obtenemos un camino que satisface ? Y si conocemos , el número de caminos que satisfacen , ¿cómo obtenemos ?
Caso 1:
Digamos que . Si tomamos un camino que satisface (rojo), ¿cómo lo extendemos a un camino que satisface ?

Los movimientos en azul son obligatorios: nuestro camino debe empezar en 0 y terminar en 0. Sin embargo, necesitamos elegir dos movimientos grises más para satisfacer . Si elegimos el movimiento 1, también debemos elegir el movimiento 2; de lo contrario, nuestro camino no conectará. De forma similar, si elegimos 3, también debemos elegir 4. ¡Nótese que elegir los caminos grises no aumenta el número de giros!
Para generalizar, asumiendo que nuestro camino construido para minimiza los giros, esto también significa que cualquier camino que construyamos de la forma de arriba para minimizará los giros también. Para la relación de con , nótese que en el ejemplo de arriba, tenemos 2 “unidades” (movimientos 1, 2 y movimientos 3, 4) de las cuales necesitamos elegir 1: ya tenemos 1 unidad, las dos azules, y necesitamos unidades en total. Así, en general, tendremos que elegir unidades de unidades, lo que nos da que .
Caso 2:
Digamos que es ahora . Tomemos un camino válido para (rojo) y transformémoslo en uno para :

Hay una razón por la que lo dibujé así, pero así es como se vería normalmente:

Sin embargo, volviendo al primer diagrama, ¿de cuántas formas se pueden dibujar los enlaces grises? Bueno, necesitamos enlazar las 2 unidades rojas con las 3 unidades azules, y el orden de las unidades rojas está fijo (no podemos enlazar la unidad roja 2 con la unidad azul 1 y la unidad roja 1 con la unidad azul 2, por ejemplo); por lo tanto, el número de formas de dibujar enlaces grises es simplemente en este caso.
Nótese que esta construcción también minimiza los giros, ya que “reutilizamos” tantos giros como sea posible (p. ej. la unidad azul 1 y la unidad roja 1 enlazadas juntas tienen la misma cantidad de giros que la unidad roja 1 sola). Así, cuando , .
Implementación
Complejidad temporal:
#include <iostream>
using namespace std;
using ll = long long;
const int A = 1e6 + 1;
const int M = 1e9 + 7;
const int N = 1e5;
ll fact[A], inv_fact[A], a[N];
// binary exponentiation:
// https://usaco.guide/gold/modular#modular-exponentiation
ll exp(ll x, ll n) {
x %= M;
ll res = 1;
while (n > 0) {
if (n % 2 == 1) { res = res * x % M; }
x = x * x % M;
n /= 2;
}
return res;
}
// https://usaco.guide/gold/combo#method-2-factorial-definition-modular-inverses---mathcalon--log-mod
ll C(ll n, ll k) { return fact[n] * inv_fact[n - k] % M * inv_fact[k] % M; }
int main() {
// precomputamos factoriales e inversos
fact[0] = inv_fact[0] = 1;
// fact[i] = i!, inv_fact[i] = inverso de i!
for (int i = 1; i < A; i++) {
fact[i] = fact[i - 1] * i % M;
// inverso de x mód M = x^(M - 2) cuando M es primo
inv_fact[i] = exp(fact[i], M - 2);
}
int n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> a[i];
// convertimos a[i] a b[i]
a[i] /= 2;
}
ll ans = 1; // caso base: C_{n - 1} = 1
for (int i = n - 2; i >= 0; i--) {
// calculamos C_i
if (a[i] > a[i + 1]) {
ans = ans * C(a[i], a[i + 1]) % M;
} else {
ans = ans * C(a[i + 1] - 1, a[i] - 1) % M;
}
}
cout << ans << endl;
}