Blue Bridge Cup Crop Hybrid (recursivo)

1. Descripción del problema:

La hibridación de cultivos es un paso importante en el cultivo de cultivos. Hay cultivos N conocidos (numerados del 1 al N), y el tiempo desde la siembra hasta la madurez del i-ésimo cultivo es Ti. Los cultivos se pueden cruzar en pares, y el tiempo de cruzamiento es el más largo de los dos. Si el tiempo de siembra del cultivo A es de 5 días y el tiempo de siembra del cultivo B es de 7 días, el tiempo dedicado a la hibridación AB es de 7 días. La hibridación de cultivos producirá cultivos fijos, y los cultivos recién producidos siguen siendo uno de los tipos de cultivos N.
Inicialmente, tiene las semillas de cultivos M (el número es ilimitado y puede soportar múltiples cruces). Se pueden realizar múltiples procesos de hibridación al mismo tiempo. Pregunte por una semilla de destino determinada, cuántos días se necesitan al menos para obtenerla.
Si hay 4 tipos de cultivo ABCD, su tiempo de madurez es de 5 días, 7 días, 3 días y 8 días. Tener inicialmente las semillas de dos cultivos AB, la semilla objetivo es D, la situación de hibridación conocida es A × B → C, A × C → D. El proceso de hibridación más corto es: del
día 1 al día 7 (la época del cultivo B), A × B → C.
Del día 8 al día 12 (época del cultivo A), A × C → D.
Se necesitan 12 días para obtener las semillas del cultivo D.
Descripción de entrada
La primera línea de entrada contiene 4 números enteros N, M, K, T, N representa el número total de tipos de cultivos (numerados del 1 al N), M representa el número de tipos de semillas de cultivos poseídos inicialmente, K representa el número de esquemas que se puede cruzar, T Indica el número de semilla de destino.
La segunda línea contiene N enteros, donde el i-ésimo entero representa el tiempo de siembra del i-ésimo cultivo Ti (1 <= Ti <= 100), y 
la tercera línea contiene M enteros, que representan respectivamente el tipo de semilla Kj (1 <= Kj ≤ M), Kj es diferente en pares.
Filas 4 a K + 3, cada fila contiene 3 enteros A, B, C, lo que indica que el cruce entre el cultivo A y el cultivo B puede obtener las semillas del cultivo C.
Entre ellos, 1 <= N <= 2000, 2 <= M <= N, 1 <= K <= 10 ^ 5, 1 <= T <= N para
garantizar que la semilla objetivo se pueda obtener mediante hibridación.
Descripción de
salida Genere un número entero para indicar el tiempo de hibridación más corto para la semilla de destino.
Muestra de entrada de salida
ejemplar
de entrada
. 6 2. 6. 4
. 5. 6. 4. 9. 4. 3
1 2
1 2. 3
1. 4. 3
2. 3. 5
. 4. 5. 6
de salida
16
Ejemplo Descripción
del día 1 al día 5, el número 1 y el número 2 Cruzan los cultivos y obtienen la semilla del cultivo número 3.
Desde el día 6 hasta el día 10, cruce los cultivos número 1 y número 3 para obtener las semillas del cultivo número 4.
Desde el día 6 hasta el día 9, cruce los cultivos No. 2 y No. 3 para obtener las semillas del cultivo No. 5.
Desde el día 11 al día 16, cruce el cultivo No. 4 con el cultivo No. 5 para obtener la semilla del cultivo No. 6.
Tomó 16 días en total.
Límite de funcionamiento
Tiempo de funcionamiento máximo: 1 s
Memoria de funcionamiento máxima: 256 M

Fuente: https://www.lanqiao.cn/problems/506/learning/

2. Análisis de pensamiento:

① Analice el problema para saber que lo más fácil de pensar es hibridar a partir de las semillas existentes, obtener la semilla de destino buscando todos los esquemas de hibridación posibles y registrar el costo durante la recursividad, pero el tamaño de los datos K del problema puede aumentar. a 10 ^ 5. Sabiendo que la búsqueda directa de todos los esquemas de hibridación posibles definitivamente se agotará, y la recursividad hacia adelante consume mucho tiempo, así que piénselo de esta manera, ¿puede funcionar lo inverso? Podemos revertir la recursividad hasta que la semilla de destino recursiva actual sea la semilla existente, por lo que al principio, podemos comenzar desde la semilla T del número de destino y seguir adelante, porque sabemos que debe haber un paso para obtener la semilla de destino. Se obtiene por hibridación. A través del recorrido de bucle, encuentre el plan de hibridación actual que puede obtener el número de semilla objetivo T, y luego use el mismo método para repetir este plan de hibridación A * B = Número de semilla A, B en C (qué plan de hibridación esperar a que se pueda obtener la semilla A y la semilla B), es decir, los números de semilla de destino de la siguiente recursión son A y B respectivamente, hasta que el número de semilla de destino recursivo actual sea una semilla existente, entonces significa que puede usar la semilla T para avanzar La semilla T objetivo se obtiene a través de una serie de cruces de las semillas existentes. Podemos escribir un método recursivo con un valor de retorno. Cuando encontramos que las semillas existentes contienen la semilla recursiva actual cuando recurrimos, significa que podemos obtener la semilla T del número objetivo a través de una serie de cruces de la semilla actual. Esto solo devuelve 0 en ese momento, y cuando vuelva a bajar, debe agregar el tiempo máximo de siembra de la hibridación A y B actual para obtener C, lo que significa el tiempo actual requerido para obtener la semilla C objetivo. comprensible. Dibuje el proceso de derivar del número de destino hasta el final para comprenderlo mejor. El código central es principalmente código recursivo:

② Al recursar, cada vez que encontramos la semilla del número objetivo que se necesita actualmente, necesitamos encontrar este número objetivo en todos los esquemas de hibridación posibles.

El retorno de 0 se debe a que la semilla objetivo actual ya existe en las semillas existentes, y cuando retrocedemos, agregamos el tiempo máximo de siembra de A y B de la semilla actual C, por lo que debemos devolver 0 al final. De hecho, no es difícil de entender. Teniendo en cuenta que solo hay una solución para obtener la semilla del número objetivo, entonces el resultado final de devolver 0 es correcto (será más fácil de entender con un ejemplo más simple), porque tengo lo agregó antes de volver a recuperar Es el tiempo máximo para obtener la semilla de destino C

③ Debido a que se usa el lenguaje Python, al principio, el esquema de hibridación de A * B = C se puede encapsular en forma de tuplas y agregar a la lista, de modo que la lista se pueda recorrer directamente para encontrar posibles híbridos durante la recursividad. Programa

3. El código es el siguiente:

from typing import List


class Solution:
    def solve(self, N: int, M: int, K: int, T: int, plantTime: List[int], seeds: List[int], program):
        def dfs(target):
            res = 0
            if target in seeds: return 0
            for i in range(K):
                if program[i][2] == target:
                    # 注意输入数据与下标的转换, 后面需要减1
                    res += max(dfs(program[i][0]), dfs(program[i][1])) + max(plantTime[program[i][0] - 1],
                                                                             plantTime[program[i][1] - 1])
                    break
            return res
        res = 10 ** 9
        # 有可能存在多个杂交的方案获取目标种子编号T这个时候需要搜索所有能够获得种子T的杂交方案
        # 从中找到一个花费最小的
        for i in range(K):
            if program[i][2] == T:
                res = min(res, max(dfs(program[i][0]), dfs(program[i][1])) + max(plantTime[program[i][0] - 1], plantTime[program[i][1] - 1]))
        return res


if __name__ == '__main__':
    N, M, K, T = map(int, input().split())
    plantTime = list(map(int, input().split()))
    seeds = list(map(int, input().split()))
    program = list()
    # program存储的是作物的杂交方案
    for i in range(K):
        A, B, C = map(int, input().split())
        # 列表中的元素为元组类型这样封装会更方便一点
        program.append((A, B, C))
    print(Solution().solve(N, M, K, T, plantTime, seeds, program))

 

Supongo que te gusta

Origin blog.csdn.net/qq_39445165/article/details/115297967
Recomendado
Clasificación