juego de piedra leetcode

Stone Game One

Alex y Lee están jugando con algunos montones de piedras. Incluso las pilas de piedras están dispuestas en una fila, y cada pila tiene pilas enteras positivas [i].

En el juego, quien tenga más piedras para decidir el resultado. El número total de piedras es impar, por lo que no hay extracción.

Alex y Lee se turnan, y Alex comienza primero. Cada ronda, el jugador toma la pila completa de piedras desde el principio o el final de la línea. Esta situación continúa hasta que no haya más montones de piedras, momento en el cual gana el jugador con más piedras en la mano.

Asumiendo que tanto Alex como Lee han jugado lo mejor posible, vuelve verdadero cuando Alex gana el juego y falso cuando Lee gana el juego.

La idea
dp [i] [j] [0] representa el valor máximo que puede obtenerse de la primera mano de la pila de i a J. Dp [i] [j] [1] representa el valor máximo obtenido por la mano trasera. La ecuación de transferencia es la siguiente:
dp [ i] [j] [0] = max (pilas [i] + dp [i + 1] [j] [1], pilas [j] + dp [i] [j-1] [1])
dp [i ] [j] [1] = min (dp [i + 1] [j] [1], dp [i] [j-1] [1]) La última transición de estado está determinada por la primera mano

class Solution:
    def stoneGame(self, piles: List[int]) -> bool:
        n=len(piles)
        dp=[[[0,0] for i in range(n+1)] for j in range(n+1)]
        for i in range(n):
           dp[i][i][0]=piles[i]
           dp[i][i][1]=0
        for l in range(1,n):
            for i in range(0,n-l):
                j=i+l
                dp[i][j][0]=max(piles[i]+dp[i+1][j][1],piles[j]+dp[i][j-1][1])
                dp[i][j][1]=min(dp[i+1][j][0],dp[i][j-1][0])
        if dp[0][n-1][0]>dp[0][n-1][1]:
            return True
        else:
            return False

¿Por qué dp tiene estados bidimensionales i y j? La definición en Stone Game 3 solo necesita una dimensión, que debe estar relacionada con la definición del problema. En el primer problema, debido a que se toma desde el principio y la cola, obviamente hay un límite límite, y en el tercer problema, se puede tomar continuamente, entonces solo tenemos un estado unidimensional.

Juego de piedra II

Alex y Lee continúan su juego de piedra. Muchas pilas de piedras están dispuestas en una fila, y cada pila tiene un número entero positivo de pilas [i]. En el juego, quien tenga más piedras para decidir el resultado.

Alex y Lee se turnan, y Alex comienza primero. Inicialmente, M = 1.

En el turno de cada jugador, ese jugador puede tomar todas las piedras restantes de la primera pila X, donde 1 <= X <= 2M. Entonces, sea M = max (M, X).

El juego continúa hasta que se quiten todas las piedras.

Asumiendo que tanto Alex como Lee han jugado lo mejor posible, devuelve la cantidad máxima de piedras que Alex puede obtener.

Ideas
El rango que se puede obtener de la primera mano no es fijo, pero sigue siendo una secuencia continua como la pregunta tres. Por lo tanto, podemos definir dp [i] [j] para representar la posición i-ésima, el valor máximo obtenido primero cuando se alcanza la posición j, y sum [i] almacena la suma del sufijo de las pilas [i]. Entonces
podemos ver que dp [i] [j] = sum [i] -min (dp [i + p] [max (p, j / 2)], donde 1 <= p y p <= (ji)

class Solution:
    def stoneGameII(self, piles: List[int]) -> int:
        n=len(piles)
        su=0
        dp=[[0 for i in range(n+1)] for j in range(n+1)]
        for i in range(n-1,-1,-1):
            su+=piles[i]
            for m in range(1,n+1):   
                if i+2*m>=n:
                    dp[i][m]=su
                    continue
                for j in range(1,2*m+1):
                    if i+j<n:
                        dp[i][m]=max(dp[i][m],su-dp[i+j][max(j,m)])
        return dp[0][1]

Juego de piedra tres

Alice y Bob están jugando con algunas pilas de piedras. Se organizan varias pilas de piedras en una fila, y cada pila de piedras corresponde a una puntuación, que es dada por la matriz stoneValue.

Alice y Bob se turnan para tomar piedras, y Alice siempre comienza primero. En el turno de cada jugador, ese jugador puede eliminar las primeras 1, 2 o 3 pilas de piedras de las piedras restantes. El juego continuó hasta que se quitaron todas las piedras.

El puntaje final de cada jugador es la suma de los puntajes correspondientes de cada pila de piedras que recibió. La puntuación inicial de cada jugador es 0. El objetivo del juego es determinar el puntaje más alto, el jugador con el puntaje más alto ganará el juego y puede haber un empate en el juego.

Supongamos que Alice y Bob adoptan la estrategia óptima. Si Alice gana, se devuelve "Alice". Si Bob gana, se devuelve "Bob". Si se devuelve un empate (mismo puntaje), se devuelve "Empate".

Ideas
El siguiente estado después de tomar la primera mano en el estado actual se convierte nuevamente en la mano reversa, y el siguiente estado en la primera mano reversa se convierte en la primera mano. Usamos dp [i] [0] para denotar el valor máximo que puede obtener la primera mano cuando se usa la i-ésima pila de piedras, y dp [i] [1] denota el valor máximo que la mano trasera puede obtener en este momento.
Luego está la ecuación de transferencia: dp [i] [0] = max (dp [i + 1] [1] + sum (stoneValue [i: i + 1]), dp [i + 2] [1] + sum (stoneValue [i: i + 2], dp [i + 3] [1] + sum (stoneValue [i: i + 3])), deje que dp [i] [0] provenga de la transición de estado i + p y
luego dp [i] [1] = dp [i + p] [0]

El código es el siguiente

class Solution:
    def stoneGameIII(self, stoneValue: List[int]) -> str:
        n=len(stoneValue)
        dp=[[0,0] for i in range(n+3)]
        dp[n-1][0],dp[n-1][1]=stoneValue[n-1],0
        for i in range(n-2,-1,-1):
            mx,mx_p=-float('inf'),-1
            for k in range(1,4):
                if i+k>n:
                    break
                tmp=(dp[i+k][1] if i+k<n else 0)+sum(stoneValue[i:i+k])
                if tmp>mx:
                    mx=tmp
                    mx_p=k
            dp[i][0]=mx
            dp[i][1]=dp[i+mx_p][0] if i+mx_p<n else 0
        if dp[0][0]>dp[0][1]:
            return "Alice"
        elif dp[0][0]<dp[0][1]:
            return "Bob"
        elif dp[0][0]==dp[0][1]:
            return "Tie"

Usando la idea de la pregunta dos, podemos optimizar el estado bidimensional a unidimensional. dp [i] representa el valor máximo obtenido primero en la posición i-ésima, luego dp [i] = suma [i] -min (dp [i + 1], dp [i + 2], dp [i + 3])

for(int n = stoneValue.size(), i = n-1; i >= 0; i--) {
            dp[i] = -0x7FFFFFFE;
            sum += stoneValue[i];
            for(int j = 1; j <= 3; j++) {
                dp[i] = max(dp[i], sum - dp[i+j]);
            }
        }
        if(sum - dp[0] == dp[0]) {
            return "Tie";
        } else if(sum - dp[0] > dp[0]) {
            return "Bob";
        }
        return "Alice";

Supongo que te gusta

Origin www.cnblogs.com/flightless/p/12748062.html
Recomendado
Clasificación