Zapallos (solución)
Intento 1 (que no es solución)
Un primer intento sería probar todas las posibilidades. Esto es, la solución final solo depende de cuántas cajas le compramos a cada agricultor. Ahora, ¿cuántas formas de hacer esto hay? Esto no hace a la solución, pero creo que es un análisis interesante de hacer.
Una forma de contar esto es imaginar que ponemos una bolita “\circ” por cada caja. Ahora lo que podemos hacer es ubicar A separadores “|”. Por ejemplo, si tenemos 7 cajas y 3 agricultores, una disposición posible es:
\underset{\text{Agricultor ficticio}}{\underbrace{ \circ \quad \circ}} | \underset{\text{Agricultor 1}}{\underbrace{ \circ \quad \circ \quad \circ}}|\underset{\text{Agricultor 2}}{\underbrace{ \quad \quad}}|\underset{\text{Agricultor 3}}{\underbrace{ \circ \quad \circ}}
El “Agricultor ficticio” es porque si bien tenemos hasta 7 cajas, podríamos comprar solo 5 en total. Si no nos gusta la figura de un “Agricultor ficticio”, podemos pensar que son las cajas que dejamos afuera.
Entonces, la cantidad de formas será igual a la cantidad de formas de ubicar los separadores en las bolitas. Esto es: \frac{10!}{3!7!}, (Recordar que n! es la cantidad de permutaciones de una palabra que tiene n letras. En nuestro caso podemos pensar a la palabra de 10 letras AAABBBBBBB, pero, necesitamos dividir por todas las permutaciones posibles entre las A's y las B's, para no contar palabras repetidas).
En general, nos queda que en el problema hay (llamo S = \sum_{a = 1}^A K_a \leq A \cdot 1200 \leq 240000)
\frac{\left (A + S\right ) !}{A!S!} = \frac{(A+S)\cdot(A+S-1)\cdots(S+1)}{A!}
Lo cual en el peor caso nos da algo así como: \frac{(240000)^{20}}{20!}. Lo cual obviamente es mucho (igual esta cota es muy burda, porque no usa que tenemos un límite M de cajas a utilizar, pero me servía más así para exponer la idea de “bolitas y separadores”).
¿Cómo hacemos entonces para resolver el problema?
Intento 2 (que sí es solución)
Por comodidad, vamos a precomputar para cada agricultor a, en qué ganancia/pérdida se incurre por comprar i cajas \forall \hspace{3pt} 1 \leq i \leq K[a] (para todas las cajas).
La idea es aprovechar la estructura que tiene el proceso que se realiza. Uno primero le compra una cierta cantidad al primer agricultor, luego otra cantidad al segundo, etc. Como siempre, lo mejor para esto es hacerse un dibujito.
Ahora, inicialmente tenemos un límite de M cajas para comprar, entonces cuando uno le va a comprar a un cierto agricultor, la cantidad de cajas que le podrá comprar, dependerá de cuántas se haya gastado en los agricultores anteriores. Teniendo esto, podemos describir el proceso.
BEST(a,m) = \text{"Lo mejor que puedo hacer comprando hasta el } \\ a \text{-ésimo agricultor, si todavía puedo meter } m \text{ cajas en el camión"}.
En el dibujito anterior, esto puede verse como: BEST(a,m) = "La mayor ganancia con la que puedo llegar al nodo “a.0”, sobrándome m cajas
Si estoy parado en a.0, ¿de dónde puedo venir? O mejor dicho, ¿De quiénes se necesitan conocer los valores para responder BEST(a,m)?
Sí o sí uno viene de comprarle al agricultor anterior, y va a depender de cuántas cajas le compró al agricultor anterior, de dónde venimos (estamos viendo en el dibujo las aristas que llegan a a.0).
Entonces, si estamos en (a,m) podemos venir de:
-
(a-1,m) : Esto significa que no le compramos nada al agricultor a-1.
-
(a-1,m+1) : Esto significa que le compramos 1 caja al agricultor a-1.
- … (a-1,m+j): Esto significa que le compramos j cajas al agricultor a-1.
-
(a-1,m+K[a-1]) : Esto significa que le compramos todas las cajas al agricultor a-1.
En realidad hay que tener en cuenta un par de cosas:
- En ninguno de esos casos puede pasar que que m+j sea mayor que M. Porque de ser así, quiere decir que en algún momento dispusimos de más de M cajas.
- Si venimos de (a-1,m+j), entonces la ganancia sería BEST(a-1,m+j) + gananciaPorComprar(a-1,j) (O sea, la ganancia o pérdida en la que se incurre por comprarle j cajas al agricultor a-1).
- Bueno, y no olvidarnos que de todas las opciones queremos la que de más grande (más ganancia).
Bueno, esta es una forma de plantear el problema y resolverlo. Se enmarca dentro de lo que es Programación Dinámica, les dejo el post en la wiki que está muy bueno.
Un detalle de implementación, quizá quede cómodo agregar un agricultor ficticio al principio y al final. Así la respuesta nos queda en:
\underset{0 \leq m \leq M}{\text{arg max}} \hspace{2pt} BEST(A+1,m)
Nos quedaría el dibujo que muestro en la siguiente figura. Además por lo que pide el problema, debemos recordar dónde se realizó cada máximo para reconstruir el camino (cuántas cajas se le compran a cada agricultor).