1. Demostración de que el algoritmo original es O(n) = n2. int fibonacci(int n) { if (n <= 0) return 0; else if (n == 1) return 1; else return fibonacci(n - 1) + fibonacci(n - 2); } Paso 1: Definir la función T(n) Condición de salida (n = 0 o n = 1): T(n) = T(cond) + T(return) = t + t = 2t Parte recursiva (n > 1): T(n) = T(cond) + T(return) + T(n-1) + T(n-2) = 2t + T(n-1) + T(n-2) Paso 1.2: Expansión de la parte recursiva de T(n) Se expande la parte recursiva: T(n) = 2t + T(n-1) + T(n-2) = 2t + [2t + T(n-2) + T(n-3)] + T(n-2) = 4t + 2T(n-2) + T(n-3) = 4t + [2t + T(n-3) + T(n-4)] + T(n-3) = 6t + 2T(n-3) + T(n-4) = ... = 2^kt + T(n-k) Paso 1.3: Aplicar la condición de salida Cuando n = 0 o n = 1: T(0) = T(1) = 2t Para obtener T(n): T(n) = 2^kt + T(n-k) = 2^nt Paso 2: Aplicar O(T(n)) O(T(n)) = O(2^nt) = O(2^n) Por lo tanto, el orden del algoritmo de Fibonacci es exponencial, O(2^n). 2. Algoritmo recursivo equivalente en C++. int fibonacci_helper(int n, int a, int b) { if (n == 0) return a; else if (n == 1) return b; else return fibonacci_helper(n-1, b, a + b); } int fibonacci(int n) { return fibonacci_helper(n, 0, 1); } 3. Demostracion que el algoritmo equivalente es O(n)=n. Paso 1: Definir la Función de Tiempo ( T(n) ) Condición de salida (n = 0 o n = 1): T(n) = T(cond) + T(return) = t + t = 2t Parte Recursiva (n > 1): T(n) = T(cond) + T(return) + T(n-1) = 2t + T(n-1) Paso 2: Expansión de la Parte Recursiva Se expande la parte recursiva: T(n) = 2t + T(n-1) = 2t + (2t + T(n-2)) = 4t + T(n-2) = 4t + (2t + T(n-3)) = 6t + T(n-3) = ... = 2kt + T(n-k) Paso 3: Aplicar la Condición de Salida Cuando n = 0 o n = 1: T(0) = T(1) = 2t Para obtener T(n) en términos de k: T(n) = 2kt + T(n-k) = 2nt Paso 4: Aplicar O(T(n)) La complejidad temporal final del algoritmo es: O(T(n)) = O(2nt) = O(n)