Acerca de la programación dinámica

La programación dinámica  es un método para resolver un problema complejo dividiéndolo en una colección de subproblemas más simples, resolviendo cada uno de esos subproblemas solo una vez y almacenando sus soluciones.
 

  1. Desmontar el complejo problema original en varios subproblemas simples.

  2. Resuelva cada subproblema solo una vez y guarde sus soluciones 

  3. Finalmente, la solución al problema original se deriva 

 

Los problemas que pueden resolverse mediante programación dinámica, suelen tener dos características

  • Subestructura óptima (principio de optimización): Al resolver la solución óptima del subproblema, se puede obtener la solución óptima del problema original.

  • Sin secuelas

    1. Una vez que se determina el estado de una determinada etapa, la evolución del proceso posterior ya no se verá afectada por los estados y decisiones anteriores (el futuro no tiene nada que ver con el pasado)

    2. Al derivar el estado de la etapa posterior, solo tenga en cuenta el valor de estado específico de la etapa anterior, no cómo se deriva este estado paso a paso 

 

Ejercicio: suma máxima de submatrices consecutivas

imagen

 

Pensamientos al principio :

Cuando vi este tema, cuando no conocía la programación dinámica, comencé a pensar en cómo resolverlo, siempre pensando en ello, y luego sin poder desarmar el problema en detalle, por lo que no hay enfoque.

 

Ideas de resolución de problemas de programación dinámica

 

1. Definición de estado

Suponga que dp (i) es la suma de la subsecuencia continua más grande que termina en nums [i] (nums es la secuencia completa)

dp es la abreviatura de (Programación dinámica)

  • La subsecuencia continua más grande que termina en nums [0] –2 es –2, por lo que dp (0) = –2

  • La subsecuencia continua más grande que termina en nums [1] 1 es 1, por lo que dp (1) = 1

  • La subsecuencia continua más grande que termina en nums [2] –3 es 1, –3, por lo que dp (2) = dp (1) + (–3) = –2

  • La subsecuencia continua más grande que termina en nums [3] 4 es 4, entonces dp (3) = 4

  • La subsecuencia continua más grande que termina en nums [4] –1 es 4, –1, por lo que dp (4) = dp (3) + (–1) = 3

  • La subsecuencia continua más grande que termina en nums [5] 2 es 4, -1, 2, por lo que dp (5) = dp (4) + 2 = 5

  • La subsecuencia continua más grande que termina en nums [6] 1 es 4, -1, 2, 1, por lo que dp (6) = dp (5) + 1 = 6

  • La subsecuencia continua más grande que termina en nums [7] –5 es 4, –1,2, 1, –5, por lo que dp (7) = dp (6) + (–5) = 1 

  • La subsecuencia continua más grande que termina en nums [8] 4 es 4, -1, 2, 1, -5, 4, por lo que dp (8) = dp (7) + 4 = 5 

2. Ecuación de transición de estado

  • Si dp (i - 1) ≤ 0, entonces dp (i) = nums [i]

  • Si dp (i - 1)> 0, entonces dp (i) = dp (i - 1) + nums [i] 

3. Establecer el estado inicial y determinar la solución final.

  • El valor del estado inicial dp (0) es nums [0] 

  • La solución final La suma de subsecuencia continua máxima es el valor máximo de todo dp (i) max {dp (i)}, i ∈ [0, nums.length) 

Resumen: todo el núcleo reside en la ecuación de transición de estado

La ecuación de transición de estado de esta pregunta es muy clara: si dp (i-1) es un número negativo, entonces dp (i) no debe combinarse con el número continuo anterior. Si es positivo, súmelos. Como cada paso es la solución óptima, el resultado es max {dp (i)}.

 

Código

func maxSubarray(nums: [Int]) -> Int {
        if nums.count  == 0  { return 0 }
        var dp = [Int](repeating: nums[0], count: nums.count)
        var maxValue = dp[0]
        for (i, value) in nums.enumerated() {
            if i >= 1 {
                let prev = dp[i - 1]
                if prev > 0 {
                    dp[i] = dp[i-1] + value
                } else {
                    dp[i] = value
                }
            }
            maxValue = max(maxValue, dp[i])
        }
        
        return maxValue
    }

 

La complejidad temporal del algoritmo anterior es O (n) y la complejidad espacial también es O (n). Porque cada dp (i) se registra

 func maxSubArray(_ nums: [Int]) -> Int {
        if nums.count  == 0  { return 0 }
        var maxValue = nums[0]
        var dp = nums[0]
        for i in 1..<nums.count {
            if dp > 0 {
                dp = dp + nums[i]
            } else {
                dp = nums[i]
            }
            maxValue = max(maxValue, dp)
        }
        return maxValue
    }

La complejidad temporal de este algoritmo es O (n) y la complejidad espacial también es O (1). Debido a que esta pregunta no necesita registrar el valor anterior, la optimización del algoritmo anterior.

Bienvenido a prestar atención a la cuenta pública de [The Way of Infinite Testing], responder [Recibir recursos] Recursos de
aprendizaje de programación de Python productos secos, automatización de la interfaz de usuario de la aplicación del marco Python + Appium , automatización de la interfaz de usuario web del marco Python + Selenium , automatización de la API del marco Python + Unittest,


Los recursos y códigos se envían gratis ~
Hay un código QR de la cuenta oficial en la parte inferior del artículo, puede escanearlo en WeChat y seguirlo.

Observaciones: Mi cuenta pública personal se ha abierto oficialmente, dedicada al intercambio de tecnología de prueba, que incluye: pruebas de big data, pruebas funcionales, desarrollo de pruebas, automatización de la interfaz API, operación y mantenimiento de pruebas, pruebas de automatización de la interfaz de usuario, etc., búsqueda pública de WeChat cuenta: "Wuliang The Way of Testing", o escanee el código QR a continuación:

 ¡Presta atención y crezcamos juntos!

Supongo que te gusta

Origin blog.csdn.net/weixin_41754309/article/details/115303316
Recomendado
Clasificación