Cómo incrementar mis habilidades en programación dinámica

La mayoría de los problemas de DP se pueden dividir en dos tipos: problemas de optimización y problemas combinatorios. Los problemas de optimización requieren que elija una solución factible para que el valor de la función objetivo se minimice (o maximice). Los problemas combinatorios solicitan la cantidad de formas de hacer algo o la probabilidad de algún evento. Echemos un vistazo más de cerca a estos tipos de problemas.

Problema de optimización DP

El problema de optimización pide elegir la mejor solución posible de acuerdo con alguna función de objetivo. Tanto las monedas como los ejemplos de LCS son del tipo de optimización. La ecuación recurrente se parece a R [s] = min (F1 (R [i], R [j],…, R [k]), F2 (R [u], R [v],…, R [w] ), …, Fl (R [q], R [p], …, R [z])), donde R es la matriz de resultados DP. Simplemente hablando, el resultado se elige como el mejor = mínimo entre los varios casos candidatos. Para cada caso, el resultado se calcula a partir de los resultados de los estados DP anteriores. Por ejemplo, en el problema de las monedas, se consideran todos los últimos casos posibles de monedas. Cada uno de ellos produce un caso en la fórmula recurrente. El resultado para el estado es un mínimo entre todos estos casos. En el ejemplo de LCS hubo tres casos: primera palabra, última letra sin usar, segunda palabra, última letra sin usar y ambas palabras, última letra usada.

A menudo es útil llenar la matriz de resultados DP con valores neutros antes de calcular cualquier cosa. El valor neutral es un resultado que no afecta la respuesta del problema con seguridad. En caso de problema de minimización, el valor neutral es infinito positivo: dado que es mayor que cualquier número, todas las fórmulas recurrentes preferirían un caso con valor finito a un elemento tan neutral. En otras palabras, el estado con resultado de valor neutral puede considerarse como un estado imposible. Tenga en cuenta que para el problema de maximización, el infinito negativo es un elemento neutral.

Los estados DP a menudo se denominan subproblemas DP porque representan algún problema para los datos de entrada que es un subconjunto de la entrada del problema completo. Por ejemplo, en el caso de LCS, cada subproblema involucra dos prefijos arbitrarios de las dos palabras originales. El método DP se basa en la propiedad óptima de la subestructura: dada la solución óptima para todo el problema, sus soluciones parciales deben ser óptimas para los subproblemas. En el caso de las monedas, significa que si la solución para todo el problema con el peso total S es óptima y contiene monedas con peso w, entonces la solución sin monedas w también debe ser óptima para el subproblema con peso total (S – w).

La propiedad óptima de la subestructura es muy importante: si no se mantiene y la solución óptima tiene la subsolución que no es óptima, entonces se descartaría en algún lugar en el medio de DP al tomar el mínimo. A menudo, la solución DP resulta ser teóricamente incorrecta porque carece de la subestructura óptima. Por ejemplo, hay un clásico problema de vendedor ambulante. Deje que el dominio de estado DP sea (k, l) -> D, donde D es la longitud mínima de la ruta simple que atraviesa exactamente k ciudades, siendo 0-th city la primera y l-th city siendo la última. La propiedad de subestructura óptima en un DP de este tipo no se cumple: dado el recorrido más corto, su ruta secundaria con la última ciudad fija y el número total de ciudades no siempre es el más corto. Por lo tanto, el DP propuesto estaría equivocado de todos modos.

Problema DP combinatorio

El objetivo del problema de DP combinatorio es encontrar varias formas de hacer algo o la probabilidad de que ocurra el evento. A menudo, el número de formas puede ser grande y solo se requiere un módulo de recordatorio. La ecuación recurrente se parece a R [s] = F1 (R [i], R [j],…, R [k]) + F2 (R [u], R [v],…, R [w]) + … + Fl (R [q], R [p], …, R [z]). La única diferencia del caso de optimización es la suma en lugar del mínimo, y cambia mucho. La suma significa que las diferentes formas de los casos F1, F2, …, Fl comprenden todas las formas de estado (s).

El ejemplo del caso combinatorio es un problema de monedas modificadas: cuente la cantidad de formas de elegir monedas para que su peso total sea igual a S. El dominio de estado es el mismo: (P) -> k donde k es la cantidad de formas de elegir monedas para que su peso total sea exactamente P. Las ecuaciones recurrentes son solo un poco diferentes en problemas combinatorios.

/ * Ecuaciones recurrentes para DP:
{k [0] = 1;
{k [P] = sum_i (k [P-Wi]); (para Wi <= P)
* /
/ * Considere los datos de entrada: S = 11, n = 3, W = {1,3,5}
La tabla de resultados de DP es:
P = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11
—— + – + – + – + – + – + – + – + – + – + – + –
k = 1 | 1 | 1 | 2 | 3 | 5 | 8 | 12 | 19 | 30 | 47 | 74
* /

También hay un valor neutral para el problema combinatorio. Como el problema combinatorio usa la sumatoria, el elemento neutral es cero. Los resultados de DP en caso combinatorio generalmente representan varias formas de hacer algo, por lo que si el resultado es cero, entonces no hay forma de hacerlo. El valor del resultado neutral significa que el caso es imposible. Puede ser útil llenar la matriz de resultados DP con valores cero, aunque generalmente se hace automáticamente. En el caso de la combinatoria, es importante que se cuente cada forma posible y que no se cuente más de una vez. La segunda condición es a veces difícil de satisfacer.

Desde mi experiencia, comience con los problemas en los que la idea es dividir el problema en partes más pequeñas y almacenar el valor en alguna estructura de datos comúnmente conocida como Memoization. Luego use estos valores almacenados y construya sobre ellos para obtener la respuesta deseada. Una vez que se sienta cómodo con el concepto de memorización, continúe con los problemas más difíciles.

Un ejemplo rápido

Nota: este problema se puede resolver mediante un enfoque directo muy sencillo (deslizamiento de ventana, etc.) pero también se puede hacer mediante programación dinámica.

Pregunta:-

Entrada = gato

Salida =

1at c1t ca1

2t c2

3


Solución:

  1. Reemplace 1 en cada posición de cada alfabeto en una palabra dada y almacénelos cada vez como un nuevo elemento en la matriz.
  2. Ahora elija cada elemento de la matriz y reemplace la letra consecutiva del número numérico a 1 y agregue todos los números consecutivos. Como tomar 1at desde la primera ubicación de la matriz y reemplazarlo como 11t, ahora agregue números consecutivos que dan 2t. Use algún tipo de estructura de datos para eliminar los duplicados.
  3. Elimine la matriz después de cada iteración completa de la matriz y almacene el resultado en una matriz de resultados.
  4. Pare cuando todos los caracteres se conviertan en forma numérica.

Otro problema popular que también se puede resolver con DP es encontrar Palindrome.

Considera este ejemplo,

Entrada = akbdbka

Si la entrada anterior es Palindrome, entonces todas sus subcadenas de longitud impar, desde el centro, también deberían ser un Palindrome. Significa comenzar desde la subcadena más pequeña posible, en este caso su carácter “d”, significa verificar la existencia de un Palíndromo elegible, debería comenzar desde el centro y construir mi camino hacia arriba. Luego tome una subcadena de longitud 3, es decir, bdb; ¿Es un palíndromo? Sí lo es, sigue adelante; de lo contrario terminar. Aumente el tamaño de la subcadena a 5 y así sucesivamente, y toda la subcadena intermedia debe satisfacer la propiedad Palindrome, hasta alcanzar la longitud de la cadena de entrada.

Nota: la longitud de entrada anterior es impar, por eso se toma un número impar de subcadenas, de lo contrario comienza desde el número par más pequeño que es mayor que cero.

Primero, resuelva pequeños problemas de programación dinámica. Luego use el conocimiento que adquiere para resolver problemas de programación dinámica más grandes.

El núcleo es eso, lo resolvemos y lo olvidamos. Hice esto. Cuando fui a problemas dependientes, no podía recordar cómo resolví los problemas anteriores, nuevamente tuve que volver a visitar, crear biblioteca / función / clase para poder reutilizarlo, si necesito modificar una función existente f1, entonces lo haría cree la nueva función f11 y edítela para resolver el nuevo problema. Además, todos los problemas clásicos de DP necesitan ser entendidos, haga una biblioteca fuera de él.

Si conoce los conceptos básicos, el problema DP tiene dos propiedades,

  1. Subestructura óptima, y
  2. Subproblemas superpuestos

La subestructura óptima es un nombre elegante para la recursividad. Una recursión en la que estamos resolviendo un subproblema varias veces, si atenuamos esa recursión y damos una solución ascendente no recursiva usando (generalmente usando algo de caché), entonces esa es la Programación Dinámica.

Lo que sugiero a la gente es que para dominar DP, primero entrene su mente en la recursividad. La mayoría de las veces, usamos la solución de recursión con un enfoque cambiado.

He explicado todo con gran detalle en mi libro … Este libro está dirigido solo a DP para entrevistas competitivas de programación y codificación:

http://www.amazon.in/Dynamic-Pro

More Interesting

¿Cuál es la última actualización en el algoritmo SEO de Google en 2017 para un rango de sitio web?

Si saco el bucle for más interno de un bucle for anidado y lo ejecuto solo, ¿cambiará la complejidad del tiempo?

¿Cómo se calculan los tiempos de conducción de Google Maps?

¿Los algoritmos están sesgados inherentemente hacia las opiniones subjetivas de sus creadores humanos?

¿Qué idioma es mejor para comprender la importancia de las estructuras de datos?

En plataformas de programación competitivas como TopCoder y CodeChef, ¿cómo sé que una competencia o proyecto es bueno para participar?

¿Por qué el tiempo de espera corta cwnd a 1 y 3 ACK duplicado a la mitad en el algoritmo de control de congestión?

¿Por qué no puedo resolver mi Cubo de Rubik de 4 x 4 x 4 como un cubo de Rubik de 3 x 3 x 3 si ya he hecho los centros y los bordes?

Cómo mejorar mi solución Java para el problema 'nodo de hoja izquierda más profundo en un árbol binario'

¿Cuánto cálculo se requiere para comprender algoritmos y redes de computadoras?

Si todos los códigos de computadora son 0s y 1s, ¿cómo reconoce y entiende la computadora estos símbolos en primer lugar?

¿Cuáles son los algoritmos necesarios para resolver div2 500 y div2 1000 fácilmente en topcoder?

¿Qué hace que un gran motor de 'recomendación de personas'?

¿Se puede usar el algoritmo de Prim para encontrar la ruta más corta desde un vértice a todos los demás vértices en un gráfico no dirigido?

¿Cómo analizaría la complejidad temporal de fibbonacci?