-
Notifications
You must be signed in to change notification settings - Fork 0
Semanas 14 y 15 Programacion Dinamica
Pasar de recursión a memoización o tabulación, definiendo estado, transición, casos base y orden de cómputo antes de codificar.
| Problema | Patrón | Función | Tests |
|---|---|---|---|
| Climbing Stairs | DP 1D con compresión | climb_stairs |
2 |
| Min Cost Climbing Stairs | Minimización DP 1D | min_cost_climbing_stairs |
2 |
| House Robber | Decisión DP 1D | house_robber |
2 |
| House Robber II | División de ciclo en dos rangos | house_robber_circular |
2 |
| Coin Change | Minimización DP 1D | coin_change |
3 |
| Decode Ways | DP 1D con ceros | decode_ways |
3 |
| Longest Increasing Subsequence | Tails + búsqueda binaria | longest_increasing_subsequence |
2 |
| Word Break | DP de prefijos | word_break |
2 |
| Unique Paths | DP de grid con compresión | unique_paths |
2 |
| Longest Common Subsequence | DP 2D con compresión | longest_common_subsequence |
2 |
| Edit Distance | DP 2D con compresión | edit_distance |
2 |
| Longest Palindromic Subsequence | DP de intervalos | longest_palindromic_subsequence |
2 |
| Partition Equal Subset Sum | Knapsack 0/1 | can_partition |
3 |
| Best Time to Buy and Sell Stock with Cooldown | DP de estados finitos | max_profit_with_cooldown |
2 |
| House Robber III | DP en árbol | house_robber_tree |
2 |
| Target Sum | Transformación a conteo de subconjuntos | target_sum_ways |
2 |
| Combination Sum IV | Conteo ordenado | combination_sum_iv |
2 |
| Maximum Product Subarray | Máximo y mínimo local | maximum_product_subarray |
2 |
| Minimum Path Sum | DP de grid con compresión | minimum_path_sum |
2 |
| Distinct Subsequences | Conteo de subsecuencias | distinct_subsequences |
2 |
Se usa cuando el estado actual solo necesita uno o dos estados anteriores.
Ejemplos:
climb_stairsmin_cost_climbing_stairshouse_robberhouse_robber_circulardecode_ways
Invariante:
- Antes de avanzar, las variables comprimidas representan exactamente los estados anteriores necesarios.
En coin_change, dp[amount] guarda la menor cantidad de monedas para formar ese monto.
Invariante:
- Un valor centinela marca montos todavía inalcanzables.
- Cada moneda intenta mejorar el estado actual desde un submonto ya calculado.
- En costo mínimo de escaleras, solo importa el costo mínimo para llegar a los dos escalones previos.
En word_break, dp[i] indica si input[..i] puede segmentarse con palabras del diccionario.
Invariante:
- Si existe un
startválido yinput[start..end]está en el diccionario, entoncesdp[end]es verdadero.
En unique_paths, longest_common_subsequence y edit_distance, se conserva solo la fila necesaria.
Invariante:
- La fila anterior representa estados ya cerrados.
- La fila actual se construye de izquierda a derecha cuando depende del estado izquierdo.
En longest_palindromic_subsequence, cada estado representa el mejor resultado dentro de input[left..=right].
Invariante:
- Si los extremos coinciden, extienden el mejor resultado interno.
- Si no coinciden, se descarta uno de los extremos y se conserva el mejor subintervalo.
En can_partition, cada número puede usarse una sola vez.
Invariante:
- Recorrer el objetivo en reversa evita reutilizar el mismo número dentro de la misma iteración.
En longest_increasing_subsequence, tails[i] guarda el menor final posible para una subsecuencia de longitud i + 1.
Invariante:
-
tailspermanece ordenado. - Reemplazar un valor no cambia la longitud encontrada, pero mejora opciones futuras.
En max_profit_with_cooldown, cada día termina en uno de tres estados:
-
hold: se conserva una acción. -
rest: no se tiene acción y se puede comprar. -
cooldown: se acaba de vender y el siguiente día no puede comprar desde ese estado.
Invariante:
- Comprar solo puede salir de
rest. - Vender solo puede salir de
hold. -
resttoma lo mejor entre seguir descansando o terminar el cooldown anterior.
En house_robber_tree, cada nodo devuelve dos estados: robarlo o saltarlo.
Invariante:
- Si se roba el nodo actual, los hijos deben saltarse.
- Si se salta el nodo actual, cada hijo elige su mejor estado.
target_sum_ways transforma signos positivos y negativos en un conteo de subconjuntos.
Invariante:
- Si
sum + targetes impar o negativo, no existe partición válida. - Recorrer en reversa evita reutilizar un número.
- Los ceros duplican el número de formas, porque
+0y-0son asignaciones distintas.
En combination_sum_iv, el orden importa.
Invariante:
-
dp[amount]suma todas las secuencias que terminan con cada candidato. - El ciclo externo debe ser el monto para permitir permutaciones distintas.
maximum_product_subarray mantiene el mejor y el peor producto que terminan en la posición actual.
Invariante:
- Un número negativo puede convertir el peor producto local en el mejor.
- Un cero reinicia el producto y también puede ser la mejor respuesta si todo lo demás es negativo.
Vector de estados:
Vec<i32>Conteos grandes antes de devolver:
Vec<i64>Estados booleanos:
Vec<bool>Diccionario para segmentación:
HashSet<&str>- Empezar a codificar sin definir qué significa
dp[i]. - Usar recursión sin memoización cuando los subproblemas se repiten.
- En knapsack 0/1, recorrer hacia adelante y reutilizar accidentalmente el mismo elemento.
- Olvidar tratar
0como caso especial en Decode Ways. - En LCS, sobrescribir estados antes de usarlos si no se separa fila previa y fila actual.
- En problemas circulares, olvidar que elegir el primer elemento excluye el último.
- En DP de intervalos, llenar la tabla en un orden que lee estados todavía no calculados.
- En cooldown, permitir comprar justo después de vender.
- En Target Sum, olvidar que los ceros multiplican las formas.
- En Maximum Product Subarray, guardar solo el máximo local y perder el efecto de negativos.
cargo testResultado al cerrar el bloque:
399 passed; 0 failed
El siguiente bloque recomendado es:
- Heaps.
- Intervalos.
- Greedy.
Primeros problemas sugeridos:
- Merge K Sorted Lists.
- K Closest Points con heap.
- Meeting Rooms II.
- Minimum Number of Arrows to Burst Balloons.