("Aproximadamente" es difícil de definir, así que sólo voy a abordar el aspecto "con precisión" u "óptimo" de tus preguntas).
Hay una buena discusión sobre la diferencia entre los algoritmos codiciosos y la programación dinámica en _Introducción a los algoritmos_ de Cormen, Leiserson, Rivest y Stein (capítulo 16, páginas 381-383 de la segunda edición).
Con respecto a su primera pregunta, he aquí un resumen de lo que tienen que decir. Tanto la programación dinámica como los algoritmos codiciosos pueden utilizarse en problemas que presentan una "subestructura óptima" (que CLRS define diciendo que una solución óptima del problema contiene en su interior soluciones óptimas de subproblemas). Sin embargo, para que la solución codiciosa sea óptima, el problema debe presentar también lo que ellos llaman la "propiedad de elección codiciosa" Es decir, se puede llegar a una solución globalmente óptima tomando decisiones localmente óptimas (codiciosas). Por el contrario, la programación dinámica es buena para los problemas que presentan no sólo una subestructura óptima, sino también subproblemas superpuestos . (Esto significa que un subproblema concreto puede alcanzarse de múltiples maneras. El algoritmo de programación dinámica calcula el valor de cada subproblema una vez y luego puede reutilizarlos cada vez que el algoritmo los vuelva a visitar).
A continuación, dan el ejemplo de la mochila 0-1 frente al problema de la mochila fraccionaria aquí . Ambas exhiben la propiedad de subestructura óptima, pero sólo la segunda exhibe además la propiedad de elección codiciosa. Por tanto, el segundo puede resolverse de forma óptima con un algoritmo codicioso (o un algoritmo de programación dinámica, aunque el codicioso sería más rápido), pero el primero requiere programación dinámica o algún otro enfoque no codicioso. Véase también el ejemplo de Henry en la otra respuesta.
También puede ser útil leer lo siguiente, que es el núcleo de su discusión sobre la diferencia y que cito en su totalidad (el énfasis es mío):
En la programación dinámica, hacemos una elección en cada paso, pero la elección puede depender de las soluciones a los subproblemas . En un algoritmo codicioso, hacemos la elección que nos parezca mejor en ese momento y luego resolvemos los subproblemas que surgen después de la elección. La elección realizada por un algoritmo codicioso puede depender de las elecciones realizadas hasta el momento, pero no puede depender de ninguna elección futura ni de las soluciones de los subproblemas . Por lo tanto, a diferencia de la programación dinámica, que resuelve los subproblemas de abajo hacia arriba, una estrategia codiciosa suele progresar de arriba hacia abajo, haciendo una elección codiciosa tras otra, reduciendo iterativamente cada instancia del problema a una más pequeña.
Básicamente, pues, la programación dinámica resuelve primero los subproblemas y luego utiliza las soluciones de los subproblemas para construir las soluciones de los problemas más grandes. Los algoritmos codiciosos se encargan primero de todo el problema mayor y cada elección codiciosa reduce el problema mayor a un subproblema más pequeño. Por lo tanto, los dos tipos de algoritmos son una especie de inversión del otro.
Con respecto a su segunda pregunta, he aquí otra cita de CLRS (p. 380):
¿Cómo se puede saber si un algoritmo codicioso resolverá un determinado problema de optimización? No hay manera en general...