Tarea 6 de Diseño de Algoritmos

Trimestre 2012 Otoño
Entrega: 12 de noviembre de 2012 a las 22:00.

Problema 1 [5 puntos]: Algunas personas piensan que los perros que ladran mucho muerden poco. Para demostrar lo contrario se quiere analizar una colección de perros y escoger tantos de ellos en una secuencia en la que tanto el número de ladridos como el número de mordidas vayan en orden creciente. Sea P un entero positivo que denota al número de perros en la colección, L[1], L[2], ..., L[P] un vector de enteros positivos indicando el número de ladridos de cada uno de los P perros y M[1], M[2], ..., M[P] el número de mordidas de cada uno de los P perros. Diseñe un algoritmo de programación dinámica que encuentre la máxima longitud S de la secuencia con las propiedades pedidas. En otras palabras, si los L perros escogidos son los perros I1, I2, ..., IS entonces M[I1] < M[I2] < ... < M[IS] y L[I1] < L[I2] < ... < L[IS]. Por ejemplo, si P = 4, L = (3, 1, 4, 2) y M = (2, 7, 1, 8) entonces S = 2 ya que se puede escoger a los perros 2 y 4 con M[2] < M[4] y L[2] < L[4]. Escriba un programa llamado muerdeZZ (donde ZZ es una clave de dos dígitos asignada por el profesor) basado en su algoritmo que acepte como entrada un número entero P, seguido de un renglón con P números enteros L[1], L[2], ..., L[P] separados por espacios y seguido de un renglón con otros P números enteros M[1], M[2], ..., M[P] y que escriba como salida la máxima longitud S de la secuencia con las propiedades pedidas. Puede suponer que todos los números involucrados son enteros del 1 al 10,000.

Ejemplo de entrada
Ejemplo de salida
4
3 1 4 2
2 7 1 8
2

Problema 2 [5 puntos]: Diseña un algoritmo usando programación dinámica para resolver el siguiente problema: Un cierto lenguaje de programación le permite al programador cortar una cadena en dos partes. Debido a que esta operación involucra copiar la cadena original, cuesta N unidades de tiempo cortar una cadena de N caracteres en dos partes. Supón que un programador quiere cortar una cadena en varias partes. El orden en el que se hagan los cortes puede afectar la cantidad total de tiempo empleada. Por ejemplo, suponga que se quiere cortar una cadena de 20 caracteres justo después de los caracteres 3, 8 y 10 (numerando los caracteres en orden ascendente, de izquierda a derecha y comenzando con el 1). Si los cortes se hicieran de izquierda a derecha, entonces el primer corte costaría 20 unidades de tiempo, el segundo costaría 17 unidades de tiempo y el tercero costaría 12 unidades de tiempo, para un total de 49 unidades de tiempo. Si los cortes se hicieran de derecha a izquierda, entonces el primer corte costaría 20 unidades de tiempo, el segundo costaría 10 unidades de tiempo y el tercero costaría 8 unidades de tiempo, para un total de 38 unidades de tiempo. Hay una forma mejor que esta que tarda 37 unidades de tiempo. Escribe un programa llamado cortacZZ (donde ZZ es la clave de dos dígitos asignada por el profesor) basado en tu algoritmo que acepte como entrada un entero positivo N (la longitud de la cadena) seguido de otro número positivo M (el número de cortes a realizar) y seguido de M números positivos X1, ..., XM (los distintos lugares donde se desea realizar los cortes, ordenados de izquierda a derecha) y que escriba como salida el tiempo mínimo T que necesita el programador para cortar la cadena en esos lugares. Puedes suponer que 1 <= M <= N <= 1000.

Ejemplo de entrada
Ejemplo de salida
20 3
3 8 10
37

Notas: Sus programas no deben leer ni escribir nada adicional a lo que se indica en el enunciado. El tiempo de ejecución de sus algoritmos será considerado como parte de la evaluación.