El algoritmo recursivo para la obtención de la subsecuencia máxima usa un tiempo lineal para calcular la suma de la mayor secuencia que atraviesa el borde, y después hace dos llamadas recursivas. Las llamadas recursivas calculan una suma que atraviesa el borde central, después hace más llamadas recursivas y así sucesivamente. El trabajo total invertido por el algoritmo es entonces proporcional al coste de las búsquedas recursivas.
/**Algoritmo de obtención de la subsecuencia de suma máxima. Encuentra la suma máxima de un subvector a [ izdo...dcho] no intenta mantener la mejor subsecuencia**/
private static int maxSumRec( int [] a, int izdo, int dcho)
{
int maxSumIzdaBorde = 0;
int maxSumDchaBorde = 0;
int sumIzdaBorde = 0;
int sumDchaBorde = 0;
int centro = (izdo + dcho) / 2;
if (izdo == dcho) //Hablamos del caso base
return a [izdo ] > 0 ? a[izdo]: 0;
int maxSumIzda = maxSumRec ( a, izdo, centro);
int maxSumDcha = maxSumRec (a, centro+1, dcho);
for (int i=centro; i>=izdo; i--)
{
sumIzdaBorde += a[ i ];
if( sumIzdaBorde > maxSumIzdaBorde)
maxSumIzdaBorde = sumIzdaBorde;
}
for (int j=centro+1; j <= dcho; j++)
{
sumDchaBorde += a[ i ];
if( sumDchaBorde > maxSumDchaBorde)
maxSumDchaBorde = sumDchaBorde;
}
return max3 (maxSumIzda, maxSumDcha, maxSumIzdaBorde + maxSumDchaBorde );
}
//Rutina visible pública
public static int maxSubSum4 ( int a [ ] )
{
return maxSumRec (a, 0, a.length-1);
}
El procedimiento Sumamax3(en este caso el que te dí antes) es de complejidad O(nlogn), puesto que su tiempo
de ejecución T(n) viene dado por la ecuación en recurrencia
T(n) = 2T(n/2) + An
con la condición inicial T(1) = 7, siendo A una constante.
Obsérvese además que este análisis es válido puesto que hemos añadido la
palabra VAR al vector a en la definición del procedimiento. Si no, se producirían
copias de a en las invocaciones recursivas, lo que incrementaría el tiempo de
ejecución del procedimiento.
Respecto a la última parte del problema, necesitamos encontrar un algoritmo
aún mejor que éste. La clave va a consistir en una modificación a la idea básica del
algoritmo anterior, basada en un algoritmo del tipo “en línea” (véase el problema
del elemento mayoritario, en este capítulo).
Supongamos que ya tenemos la solución del problema para el subvector
a[prim..i–1]. ¿Cómo podemos extender esa solución para encontrar la solución de
a[prim..i]? De forma análoga al razonamiento que hicimos para el algoritmo
anterior, la subsecuencia de suma máxima de a[prim..i] puede encontrarse en
a[prim..i–1], o bien contener al elemento a[i].
Esto da lugar a la siguiente función...