He visto varias discusiones e intentos de código para resolver el problema "String reduction" de interviewstreet.com, pero ninguno de ellos lo hace mediante programación dinámica.Resolver el desafío de "reducción de cadena"
enumerados en la sección Dynamic Programming, el problema se describe como sigue:
Dada una cadena que consta de A, B y C de, podemos realizar la siguiente operación: tomar cualquier dos personajes distintas adyacentes y reemplazarlo con el tercer personaje Por ejemplo, si 'a' y 'c' son adyacentes, pueden reemplazarse por 'b'.
¿Cuál es la cadena más pequeña que puede resultar al aplicar esta operación varias veces?
El problema se puede resolver utilizando exhaustiva búsqueda de fuerza bruta, creando un árbol de todas las sustituciones posibles:
// this is more or less pseudo code from my head
int GetMinLength(string s)
{
// solve edge cases
if (s.Length == 1) return 1;
if (s.Length == 2) return ReduceIfPossible(s);
// recursive brute force
int min = s.Length;
for (int i = 0; i<s.Length-1; i++)
{
if (s[i] != s[i+1])
{
var next = GetMinLength(
s.Substring(0, i) +
Reduce(s[i], s[i + 1]) +
s.Substring(i + 2)
);
if (next < min) min = next;
}
}
}
Esta falla, obviamente, para ampliar la N
(N <= 100
), por lo que estoy tratando de romper en subproblemas más pequeños, memorizarlos y fusionar resultados.
El problema es que no puedo determinar el estado que tendría "optimal substructure", necesario para aplicar la programación dinámica (o en otras palabras, para "fusionar" los resultados de los sub-problemas). Minimizar una parte de la cadena no garantiza que la cadena final sea realmente la solución más pequeña.
¿Cuál sería el subproblema "estado" en este caso, que podría fusionarse hacia la solución final?
@Dilbert Exactamente. Pero conviértalo en una búsqueda anidada: puedes buscar por una cosa y por la otra. (Esta tabla es más fácil de generar comenzando al final de la cadena y luego trabajando hacia atrás.) – btilly
¿Podría aclarar el primer paso un poco más? Creo que quieres que construya una tabla de todos los bloques de longitud inferior o igual a la cadena problema que puede reducirse a uno de los tres caracteres. Pero, ¿a qué te refieres con "por personaje con el que terminas, por posición inicial"? Soy un novato en DP. – gautam1168
@ gautam1168 Quise decir exactamente lo que dije. :-) Dado un carácter final y una posición de inicio, necesita una lista de todos los puntos finales de los rangos donde puede colapsar desde esa posición de inicio hasta ese punto final y terminar con ese personaje. Esto requiere resolver un problema de DP para cada punto de inicio que puede resolverse si ya ha resuelto el mismo problema para todos los posteriores. (Tenga en cuenta que deberá fusionar muchos rangos. Busque "colas de prioridad" para obtener información que lo ayude). – btilly