Descubriendo ADN
Los biólogos han descubierto una extraña molécula de ADN, mejor descrita como una secuencia de N caracteres del conjunto . Una secuencia improbable de mutaciones ha dado como resultado una cadena de ADN que consiste únicamente en A. Los biólogos lo encontraron muy extraño, así que comenzaron a estudiar las mutaciones con mayor detalle.
Descubrieron dos tipos de mutaciones. Un tipo resulta en cambiar un solo carácter de la secuencia \((A → B)\) o \((B → A)\). El segundo tipo cambia un prefijo completo de la secuencia, reemplazando específicamente todos los caracteres de las posiciones de 1 a K (para algunos K entre 1 y N, inclusive) con el otro carácter (A con B, B con A).
Calcular el menor número posible de mutaciones que podrían convertir la molécula inicial a su estado final (conteniendo sólo caracteres A). Las mutaciones pueden ocurrir en cualquier orden.
ENTRADA
La primera línea de entrada contiene el número entero positivo , la longitud de la molécula. La segunda línea de entrada contiene una cadena con N caracteres, siendo cada carácter A o B. Esta cadena representa el estado inicial de la molécula.
SALIDA
La primera y única línea de salida debe contener el número mínimo de mutaciones requerido.
Entrada Ejemplo
4
ABBA
Salida Ejemplo
2
Entrada Ejemplo
5
BBABB
Salida Ejemplo
2
Entrada Ejemplo
12
AAABBBAAABBB
Salida Ejemplo
4
Comments
El ejercicio se puede realizar sin uso de
Programación Dinámica
con complejidad algorítmica de O(N) en tiempo y memoria.y por qué puede salir std::bad_alloc?
Quizás sea MLE
Ah, muchas gracias por su ayuda. Aún no he logrado hacerlo bien, pero entendí su explicación.
Saludos. Pueden revisar mi código?, con los casos de prueba funciona. Lo hice con una función recursiva que dada la longitud n de la cadena cad, sea i la posición actual, si cad[i] es diferente de 'A' (o sea, cad[i] =='B'), realizar dos cambios:
Cada vez que llamo a la función me encargo de haber sacado una copia de la cadena actual y voy sumando en una variable el número de cambios realizados y cuando n==0, (f(0)), añado ese valor a un arreglo, finalmente doy como salida, al valor mínimo del arreglo. Está claro que consume mucha memoria, son muchas llamadas recursivas y las copias de las cadenas son varias. Es por eso, que les pregunto si pueden recomendarme alguna alternativa a esto, estoy seguro de que en mi código la respuesta a cada caso es correcta. Muchas gracias por su atención.
Te explico mi solución con DP. Definamos a como la mínima cantidad de movimientos que necesitamos para que el prefijo hasta la posición sea , sólo va tomar dos valores si estamos analizando la cadena original, y si estamos analizando la cadena original invertida (o sea, todas las se transforman en y viceversa, por ejemplo, la cadena invertida de es ).
La solución nos queda en . Esto tiene una complejidad en tiempo y memoria. Se pueden hacer optimizaciones en memoria para que quede pero no es necesario en este problema.