Programa de Python para la subsecuencia creciente más larga

El problema de la subsecuencia creciente más larga (LIS) es encontrar la longitud de la subsecuencia más larga de una secuencia dada de modo que todos los elementos de la subsecuencia se clasifiquen en orden creciente. Por ejemplo, la longitud de LIS para {10, 22, 9, 33, 21, 50, 41, 60, 80} es 6 y LIS es {10, 22, 33, 50, 60, 80}. subsecuencia creciente más largaMás ejemplos:

Input  : arr[] = {3, 10, 2, 1, 20}
Output : Length of LIS = 3
The longest increasing subsequence is 3, 10, 20

Input  : arr[] = {3, 2}
Output : Length of LIS = 1
The longest increasing subsequences are {3} and {2}

Input : arr[] = {50, 3, 10, 7, 40, 80}
Output : Length of LIS = 4
The longest increasing subsequence is {3, 7, 40, 80}

Subestructura óptima: Sea arr[0..n-1] la array de entrada y L(i) la longitud del LIS que termina en el índice i, de modo que arr[i] es el último elemento del LIS. Entonces, L(i) puede escribirse recursivamente como: L(i) = 1 + max( L(j) ) donde 0 < j < i y arr[j] < arr[i]; o L(i) = 1, si tal j no existe. Para encontrar el LIS para una array dada, necesitamos devolver max(L(i)) donde 0 < i < n. Por lo tanto, vemos que el problema LIS satisface la propiedad de subestructura óptima ya que el problema principal se puede resolver utilizando soluciones a los subproblemas. A continuación se muestra una implementación recursiva simple del problema LIS. Sigue la estructura recursiva discutida anteriormente. 

Python

# A naive Python implementation of LIS problem
 
""" To make use of recursive calls, this function must return
 two things:
 1) Length of LIS ending with element arr[n-1]. We use
 max_ending_here for this purpose
 2) Overall maximum as the LIS may end with an element
 before arr[n-1] max_ref is used this purpose.
 The value of LIS of full array of size n is stored
  in * max_ref which is our final result """
 
# global variable to store the maximum
global maximum
 
def _lis(arr, n ):
 
    # to allow the access of global variable
    global maximum
 
    # Base Case
    if n == 1 :
        return 1
 
    # maxEndingHere is the length of LIS ending with arr[n-1]
    maxEndingHere = 1
 
    """Recursively get all LIS ending with arr[0], arr[1]..arr[n-2]
       IF arr[n-1] is smaller than arr[n-1], and max ending with
       arr[n-1] needs to be updated, then update it"""
    for i in xrange(1, n):
        res = _lis(arr, i)
        if arr[i-1] < arr[n-1] and res + 1 > maxEndingHere:
            maxEndingHere = res + 1
 
    # Compare maxEndingHere with overall maximum. And
    # update the overall maximum if needed
    maximum = max(maximum, maxEndingHere)
 
    return maxEndingHere
 
def lis(arr):
 
    # to allow the access of global variable
    global maximum
 
    # length of arr
    n = len(arr)
 
    # maximum variable holds the result
    maximum = 1
 
    # The function _lis() stores its result in maximum
    _lis(arr, n)
 
    return maximum
 
# Driver program to test the above function
arr = [10, 22, 9, 33, 21, 50, 41, 60]
n = len(arr)
print "Length of lis is ", lis(arr)
 
# This code is contributed by NIKHIL KUMAR SINGH
Producción:

Length of lis is  5

Complejidad de tiempo : O(2 n )

Espacio Auxiliar : O(1)

Subproblemas superpuestos: teniendo en cuenta la implementación anterior, el siguiente es un árbol de recurrencia para una array de tamaño 4. lis(n) nos da la longitud de LIS para arr[].

              lis(4)
        /        |     
      lis(3)    lis(2)   lis(1)
     /           /
   lis(2) lis(1) lis(1)
   /
lis(1)

Podemos ver que hay muchos subproblemas que se resuelven una y otra vez. Por lo tanto, este problema tiene la propiedad de subestructura superpuesta y el recálculo de los mismos subproblemas se puede evitar mediante Memoización o Tabulación. A continuación se muestra una implementación tabulada para el problema LIS. 

Python

# Dynamic programming Python implementation of LIS problem
 
# lis returns length of the longest increasing subsequence
# in arr of size n
def lis(arr):
    n = len(arr)
 
    # Declare the list (array) for LIS and initialize LIS
    # values for all indexes
    lis = [1]*n
 
    # Compute optimized LIS values in bottom up manner
    for i in range (1, n):
        for j in range(0, i):
            if arr[i] > arr[j] and lis[i]< lis[j] + 1 :
                lis[i] = lis[j]+1
 
    # Initialize maximum to 0 to get the maximum of all
    # LIS
    maximum = 0
 
    # Pick maximum of all LIS values
    for i in range(n):
        maximum = max(maximum, lis[i])
 
    return maximum
# end of lis function
 
# Driver program to test above function
arr = [10, 22, 9, 33, 21, 50, 41, 60]
print "Length of lis is", lis(arr)
# This code is contributed by Nikhil Kumar Singh
Producción:

Length of lis is 5

Tiempo Complejidad : O(n 2 )

Espacio auxiliar : O(n)

Consulte el artículo completo sobre programación dinámica | ¡ Establezca 3 (Subsecuencia creciente más larga) para obtener más detalles!

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *