Base del algoritmo: programación dinámica

Tabla de contenido

El zen de la programación dinámica

Resolver secuencias de Fibonacci en varias latitudes

¿Qué es la secuencia de Fibonacci?

esquema recursivo ingenuo

problema de recursividad ingenuo

Fib Top-Down, esquema de memorando

Método Fib de abajo hacia arriba


El zen de la programación dinámica

La programación dinámica es la parte más interesante de la parte básica del algoritmo. He estado pensando durante muchos días, cómo resumir la programación dinámica en pocas palabras, como el resumen del algoritmo anterior, y luego doy algunas preguntas para que todos practiquen hasta dominarlas. Toma este conocimiento por completo.

Luego descubrí que, como la estrategia codiciosa, la programación dinámica no es una rutina fija, sino una especie de pensamiento: [Usar la acumulación pasada para resolver problemas actuales] Llamo a este pensamiento el Zen de la programación dinámica.

Resolver secuencias de Fibonacci en varias latitudes

¿Qué es la secuencia de Fibonacci?

Fibonacci se puede generalizar con una cadena de números:

1,1,2,3,5,8,....,num[n-1],num[n],num[n-1]+num[n]

La siguiente es su estructura recursiva, a saber, num[n] = num[n-1] + num[n-2] si n >= 2

esquema recursivo ingenuo

Podemos usar esta regla para hacer un programa para calcular el tamaño del valor N-ésimo de una manera muy simple:


int fib(int n) {
    if(n<=0) return 0;
    if(n<=2) return 1;
    return fib(n-1) +fib(n-2);
   
}

Aquí está la estructura de ejecución de este programa:

 Descomponemos un problema de tamaño N en dos problemas de tamaño N-1 y N-2, y luego continuamos dividiendo hasta que el problema se convierte en un problema resuelto, como caer en fib(1), fib(2) en adelante.

problema de recursividad ingenuo

Luego, cuando realmente ejecutemos este código, encontraremos que una vez que el valor que buscamos sea mayor, ¡el tiempo requerido para el cálculo será muy grande! Esto está relacionado con nuestra complejidad de tiempo. No es difícil ver el árbol anterior. Si cada nodo representa lo que queremos calcular una vez, entonces necesitamos calcular 2^(n -1) veces.

Necesitamos estudiar cuál es el problema con este árbol. Es obvio que hay demasiados cálculos repetidos. Cada vez que se calcula un fib(x), el valor debe rastrearse hasta fib(1) y fib(2). ¿Hay alguna forma de usar directamente el valor calculado antes? en lugar de volver a calcularlo de nuevo.

Fib Top-Down, esquema de memorando

Esta vez solicitamos un espacio de tamaño N antes de que comience el algoritmo. Este espacio se usa para registrar el valor calculado. Cuando se vuelve a usar más tarde, el valor en el espacio de caché se usa directamente en lugar de recalcularse.

El caché es algo similar al memo que usamos habitualmente, y el cálculo también es de arriba hacia abajo, por lo que este método también se denomina método de arriba hacia abajo o método de memo.

el código se muestra a continuación:

int _fib(int n, int* cache) {
   if(n<=0) return 0;
   if(n<=2) return 1;
   int num1 = 0;
   int num2 = 0;
   if(cache[n-1] != -1) {
    num1  = cache[n-1];
   }
   else {
    num1 = _fib(n-1);
    cache[n-1] = num1;
   }
   if(cache[n-2] !=-1)
   {
    num2 = cache[n-2];
   }
   else {
    num2 = _fib(n-2);
    cache[n-2] = num2;
   }
   return num1 + num2;

}
int fib(int n) {
    int *cache = (int*)malloc(sizeof(int)*n);
    for(int i =0;i<n;i++) {
        cache[i] = -1;
    }
    return _fib(n, cache);
    
}

Método Fib de abajo hacia arriba

Debido a que Fibonacci se conoce a pequeña escala y se pueden obtener escalas más grandes en base a fib(1) y fib(2), se puede realizar utilizando el método de abajo hacia arriba.

Es decir, para encontrar fib(n), calcule fib(3) a partir de fib(1)+fib(2), y luego obtenga fib(4) a partir de fib(2)+fib(3), hasta que fib(n ) .

Aquí está el código:

int fib(int n) {
    if (n<=0) return 0;
    if (n<=2) return 1;
    int num1 = 1;
    int num2 = 1;
    for(int i = 2;i<n;i++) {
       int tmp = num1+num2;
       num1 = num2;
       num2 = tmp;
    }
    return num2;
}

Supongo que te gusta

Origin blog.csdn.net/qq_32378713/article/details/128109447
Recomendado
Clasificación