Vengo de un fondo de física, y por lo tanto, muchas matemáticas. Encuentro problemas fáciles de detectar que se adaptan bien a las soluciones de programación recursiva / dinámica al encontrar similitudes con la prueba por inducción .
En prueba por inducción tiene dos partes:
- demuestras que si algo es cierto para la iteración N, también es cierto para la iteración N + 1
- demuestras que es cierto para la iteración 1
En programación recursiva / programación dinámica:
- identifica una condición de salida (por ejemplo, conecta la solución para la iteración 1)
- calcula la solución para la iteración N dada la solución para la iteración N-1
Entonces, como respondieron otros, es una cuestión de experiencia y de captar las pistas, pero puedes reutilizar otras habilidades para guiarte. Después de eso, debe tener siempre las dos partes que mencioné: si no lo hace, entonces no funcionará.
Por ejemplo, para generar todas las permutaciones de un conjunto:
- condición de salida: si solo tiene un elemento, devuélvalo
- recursividad: las permutaciones de un conjunto de N elementos son los N conjuntos de permutaciones que obtienes al elegir cada elemento y combinarlos con todos los conjuntos N-1 de (muchas) permutaciones del subconjunto que obtienes al eliminar el elemento.
Nunca había implementado un único solucionador de programación dinámica (mi experiencia es matemática / física / computación numérica aplicada, no CS) hasta hace unos años, cuando comencé a resolver los problemas del Proyecto Euler . Los problemas que se pueden resolver con DP allí (por ejemplo , 76 , 158 , 161 , 242, pero hay muchos más) resultó ser mi tipo favorito. Definitivamente mejorarás al detectar cuándo será una técnica útil: básicamente busca cosas que parezcan que podrían resolverse mediante algún tipo de enfoque recursivo, de dividir y conquistar, donde también es posible domar la explosión de caminos que necesitan para ser explorado reconociendo subproblemas recurrentes y reutilizando los resultados previamente calculados; poder identificar el vector de estado mínimo para memorizar, y qué "historia" irrelevante se puede borrar, es el paso crucial.
fuente