Divide y vencerás
Programación Dinámica
template<typename T_>
void mergeSort(T_ arr[], int low, int high)
{
if(low < high)
{
int mid = (low + high)/2;
// Ordenar recursivamente
// las mitades del arreglo
mergeSort(arr, low, mid);
mergeSort(arr, mid + 1, high);
// Mezclar las mitades del
// arreglo ordenadas
merge(arr, low, mid, high);
}
}template<typename S_>
void merge(S_ arr[], int low, int mid, int high)
{
S_ *b = new int[high - low + 1];
int h = low;
int i = 0;
int j = mid +1;
// Mezcla las dos mitades ordenadas en
// interaciones anteriores
while(h <= mid && j <= high)
{
if(arr[h] <= arr[j])
{
b[i] = arr[h];
++h;
}
else
{
b[i] = arr[j];
++j;
}
++i;
}
// Completa el arreglo con
// los valores restantes
if(h > mid)
{
for(int k = j; k <= high; ++k)
{
b[i] = arr[k];
++i;
}
}
else
{
for(int k = h; k <= mid; ++k)
{
b[i] = arr[k];
++i;
}
}
// Mover la parte ordenada
// al arreglo original
memcpy(arr + low, b,
(high - low + 1) * sizeof(S_));
delete[] b;
}donde:
a = número de llamadas recursivas (>= 1)
b = el factor de reducción de los datos de entrada (> 1)
d = exponente del tiempo de ejecución en el paso de combinación (>= 0)
Entonces:
T(n) =
O(n^d log n)
O(n^d)
O(n^(log_b a))
Si a = b^d (caso 1)
Si a < b^d (caso 2)
Si a > b^d (caso 3)
a = b^d (caso 1), entonces: T(n) = O(n log n)
Consiste en dividir el problema en subproblemas más pequeños y simples hasta llegar a un punto donde la solución del problema es trivial.
Se utiliza principalmente cuando en la resolución de los subproblemas recursivamente se pueden traslapar las soluciones.
Dado un conjunto de nodos, sus caminos y el costo de recorrer estos caminos, encontrar el camino más corto y con menos costo entre dos nodos.