Leetcode brushing record-174. Juego de mazmorra (se han agregado pensamientos, con estricta derivación matemática)

Inserte la descripción de la imagen aquí
Esta pregunta es difícil, no es difícil pensar en la idea de la programación dinámica,
sino en cómo considerar los subproblemas, el orden de procesamiento y las ecuaciones de transición de estado.

Primero reformulamos los requisitos del tema como
"En cualquier momento, el valor de salud del caballero x es mayor o igual a 1"

A continuación, definimos de acuerdo con los requisitos del título, suponiendo que el tamaño de la mazmorra sea {mxn}
**

El significado de DP [i] [j] es hacer que el caballero pase de i, j a la esquina inferior derecha durante todo el proceso. El volumen de sangre inicial no es inferior a 1, y finalmente se puede obtener DP [0] [0].

** **

Entonces, ¿es de arriba a la izquierda a la derecha o de abajo a la derecha a la izquierda?
Primero decidamos.
Supongamos que el valor de vida inicial del caballero es x, y use a para representar la matriz bidimensional de la mazmorra.

Según la experiencia de la planificación dinámica habitual del movimiento de matriz bidimensional,
simplificaremos primero el problema y lo dividiremos en los siguientes tres casos.

1. Si el tamaño de la mazmorra es {1x1} (solo 1 cuadrícula)
En este momento, no necesitamos considerar la dirección de la solución del subproblema. El
caballero solo necesita entrar en la única habitación y mantenerla después de que el valor de salud interactúa con esta casa. al menos uno de la sangre
es decir,
Inserte la descripción de la imagen aquí
resolver para
Inserte la descripción de la imagen aquí

Como necesitamos obtener el valor más bajo posible de la vida inicial, podemos tomar directamente el signo igual delante de max

2. Si el tamaño de la mazmorra es {1 xn} o {mx 1}
En este momento, ¡debemos considerar la dirección en la que se resuelve el subproblema!

Tenemos un {1} x n (1 filas y n columnas) como un ejemplo de la mazmorra
esta es una mazmorra
a = [[a [0] [0], a [0] [1], ..., a [0] [n-1]]

Supongamos que superior izquierda (a [0] [0] ) a la parte inferior derecha (a [0] [n- 1])
a través de la primera rejilla, similar a la anterior "1",
no
Inserte la descripción de la imagen aquí
, pero esta vez, si no saben una [0] [1] ~ a [0] [n-1] El valor
de dp [0] [0] no se puede derivar porque no conocemos la siguiente cuadrícula, por lo que no podemos determinar el valor de salud inicial.

¡Por lo tanto, debemos considerar la evolución desde la parte inferior derecha a la superior izquierda!

Por lo tanto, primero consideramos que si comenzamos desde la última cuadrícula a [0] [n-1], ya que también desencadena una interacción de valor de vida
, similar a "1",
Inserte la descripción de la imagen aquí
movemos el punto de partida a la izquierda a [0] [n -2]
Si comenzamos desde un [0] [n-2] con el valor de salud x, entonces
Inserte la descripción de la imagen aquí
estamos obligados a cambiar la tercera línea de arriba,
Inserte la descripción de la imagen aquí
para que podamos fusionar las expresiones de la segunda y tercera línea Y obtén el siguiente resultado
Inserte la descripción de la imagen aquí

¿En este momento, encontramos milagrosamente que la fórmula a la derecha después de la fusión no es DP [0] [n-1]? ?
Por lo tanto, sustituimos DP [0] [n-1] para obtener, y
Inserte la descripción de la imagen aquí
luego cambiamos el término a [0] [n-2] en la segunda línea de expresión, para que sea
Inserte la descripción de la imagen aquí
fácil
Inserte la descripción de la imagen aquí
obtener el requisito mínimo, tomar el signo igual, obtener
Inserte la descripción de la imagen aquí
Para esta fórmula, generalizamos a la conclusión general de esta mazmorra de formas
Inserte la descripción de la imagen aquí

De manera similar, para la mazmorra de {mx 1} (m filas y 1 columna), podemos sacar una conclusión similar: de
Inserte la descripción de la imagen aquí
esta manera, resolvimos la situación de una fila con múltiples columnas, o una columna con múltiples filas

3. En general, eso es {mxn} (la mazmorra tiene m filas yn columnas, las cuales son> 1).
Como ya hemos concluido en "2",
en la premisa de que solo puede elegir moverse hacia la derecha o hacia abajo, una
sola fila O una sola columna de mazmorras, el valor de DP de cada cuadrícula solo está relacionado con esta fila o columna

Incluso si hay m filas yn columnas,
si comenzamos desde la última fila, entonces solo tenemos una ruta, es decir, yendo hacia la derecha (no tiene nada que ver con el valor de a en otras filas),
si enviamos desde la última columna, entonces solo tenemos una ruta, a saber Todo el camino hacia abajo (no tiene nada que ver con el valor de a en otras columnas),
por lo que inicializamos las dos filas inferiores y la más a la derecha de las m filas yn columnas de acuerdo con las dos últimas fórmulas en "2"

En otras palabras, para llenar la matriz DP,
podemos inicializar la parte gris en la figura a continuación de acuerdo con la conclusión obtenida anteriormente.
Inserte la descripción de la imagen aquí
A continuación, comenzamos a llenar desde un [m-2] [n-2], y podemos llenar el m-ésimo primero. 2 filas, también puede llenar la columna n-2
primero. Completemos primero el comportamiento m-2, como se muestra a continuación (en adelante, usamos verde para indicar la cuadrícula inicializada).
Inserte la descripción de la imagen aquí
Según la experiencia en el tratamiento de tales problemas, sub-problema Bloqueado en una cuadrícula local de 2x2.
En el orden de la figura anterior, podemos asegurarnos de que los valores DP debajo de la cuadrícula i, j, el lado derecho y la parte inferior derecha del valor DP a calcular se conozcan cada vez
. Como se muestra en
Inserte la descripción de la imagen aquí
la siguiente figura De i, j a i + 1, j + 1, solo tenemos dos opciones, a saber
(1) i, j-mover hacia abajo-> i + 1, j-mover hacia la derecha-> i + 1, j + 1
(2) i, j-desplazamiento a la derecha-> i, j + 1-desplazamiento hacia abajo-> i + 1, j + 1
Si (1),
supongamos que la vida inicial es x, existe
Inserte la descripción de la imagen aquí
su El significado es que la vida inicial no es menor que 1, y el valor mínimo requerido después de i, j no es menor que 1 y no menor que i + 1, j

Por lo tanto,
Inserte la descripción de la imagen aquí
considerando la fórmula recursiva anterior, podemos asegurarnos de que los DP que se hayan obtenido no sean inferiores a 1 (también se puede entender que el volumen sanguíneo inicial no debe ser inferior a 1)
. La fórmula anterior se puede simplificar
Inserte la descripción de la imagen aquí
a (2).
Inserte la descripción de la imagen aquí

Luego está la clave, porque hay dos caminos por recorrer, queremos encontrar el valor mínimo requerido,
por lo tanto, siempre que haya uno que cumpla con el valor de vida es mayor o igual a 1, por lo tanto, tomamos las dos desigualdades anteriores O,
es decir, dejemos que x es mayor o igual que el menor de los dos máximos

Es decir, cuando 0 ≤ i ≤ m-2 y 0 ≤ j ≤ n-2
Inserte la descripción de la imagen aquí
cuando i = m-1 y
Inserte la descripción de la imagen aquí
j = n-1 de
Inserte la descripción de la imagen aquí
esta manera, obtenemos la ecuación de transición de estado de la programación dinámica

class Solution:
    def calculateMinimumHP(self, dungeon: List[List[int]]) -> int:
        m = len(dungeon)
        n = len(dungeon[0])
        if m == 1 and n == 1:#1x1的地牢
            return max(1,1-dungeon[0][0])
        elif m == 1 and n != 1:#1xn的地牢
            newlist = []
            for i in range(n):
                newlist.append(-1)
            newlist[-1] = max(1,1-dungeon[0][-1])
            for i in range(n-1):
                tempindex = n - i - 2
                newlist[tempindex] = max(1,newlist[tempindex+1] - dungeon[0][tempindex])
            return newlist[0]
        elif m != 1 and n == 1:#nx1的地牢
            newlist = []
            for i in range(m):
                newlist.append(-1)
            newlist[-1] = max(1,1-dungeon[-1][0])
            for i in range(m-1):
                tempindex = m - i - 2
                newlist[tempindex] = max(1,newlist[tempindex+1] - dungeon[tempindex][0])
            return newlist[0]
        #以下针对mxn的地牢,m和n都大于1
        #初始化一个m行n列的dplist
        print('地牢的size为',m,n)
        newlist = []
        for i in range(m):
            templist = []
            for j in range(n):
                templist.append(-1)            
            newlist.append(templist)
        #我们先初始化最下面一行和最右边一列
        #先初始化最右下角的
        newlist[m-1][n-1] = max(1,1 - dungeon[-1][-1])
        tempinit = newlist[-1][-1]
        #最下面一行,共n-1个待补充的数字
        for i in range(n-1):
            tempindex = n - i - 2
            newlist[-1][tempindex] = max(1,newlist[-1][tempindex+1] - dungeon[-1][tempindex])
        #最右边一列,共m-1个待补充的数字
        for j in range(m-1):
            tempindex = m - j - 2
            newlist[tempindex][-1] = max(1,newlist[tempindex+1][-1] - dungeon[tempindex][-1])
        #从[m-2][n-2]开始填充,一直到[0][0],共(m-1)x(n-1)个
        #先从倒数第二行倒数第二列开始,然后是倒数第二行倒数第三列,......
        for i in range(m-1):
            tempi = m - i - 2
            for j in range(n-1):
                tempj = n - j - 2
                newlist[tempi][tempj] = max(1,min(newlist[tempi+1][tempj],newlist[tempi][tempj+1])-dungeon[tempi][tempj])
        print(newlist)
        return newlist[0][0]


Publicado 43 artículos originales · elogiado 14 · 20,000+ visitas

Supongo que te gusta

Origin blog.csdn.net/weixin_41545780/article/details/105132516
Recomendado
Clasificación