🍲Beginners Guide to “LeetCode 808: Sopa Serviing” (C ++ | JavaScript | Python)
Recebemos duas sopas, A e B, cada uma começando com n ml. Em cada turno, o programa escolhe aleatoriamente uma das quatro operações de porção a seguir, cada uma com igual probabilidade (0,25): sirva 100 ml de A, 0 ml de B serve 75 mL de A, 25 ml a partir de B, a 50 ml de A, 50 ml de B servir a 25 ml de A, 75 mL de B, a partir de B quando A, A ou B se torna vazia. Se uma operação pedir para servir mais sopa do que está disponível, ela serve apenas o que resta. O objetivo é calcular a probabilidade de que a sopa A seja esvaziada antes de B, mais metade da probabilidade de que ambos fiquem vazios na mesma etapa. A intuição cada vez reduz a A e B. o resultado depende de qual sopa termina primeiro ou se ambas terminam ao mesmo tempo. As quatro operações formam uma estrutura de ramificação probabilística, e o problema pode ser visto como calculando o resultado esperado de uma árvore de probabilidade. Podemos usar memórias para armazenar os resultados de subproblemas sobrepostos. É importante ressaltar que quando N se torna grande (especificamente, acima de 4500), o resultado converge muito próximo a 1,0. Portanto, podemos curto-circuito o cálculo nesses casos. Para simplificar os cálculos, convertemos n em unidades de 25 ml. Isso ajuda a limitar o número total de estados que precisamos calcular. Abordagem Definimos uma função recursiva P (a, b) que retorna a probabilidade de que a sopa A seja esvaziada antes de B (mais metade se elas esvaziam ao mesmo tempo), começando de unidades de unidades A e B de B. Reduzimos o volume de sopa em unidades de 25 ml. Usamos um tamanho de matriz 2D[a][b] Memoção dos resultados para evitar a recalculação do mesmo estado. Solução da classe C ++ Code {public: Double p (int a, int b) {if (a <= 0 && b <= 0) retorna 0.5; if (a <= 0) retornar 1; if (b <= 0)
return 0;
auto& res = size[a][b];
if (res == 0)
res = 0.25 * (p(a – 4, b) + p(a – 3, b – 1) + p(a – 2, b – 2) + p(a – 1, b – 3));
return res;
}
double soupServings(int n) {
if (n > 4500) retornar 1; int m = teto (n / 25.0); retornar p (m, m); } tamanho duplo[300][300]; }; Digite o modo de tela completa Sair do modo de tela cheia JavaScript Versão var sopServings = function (n) {if (n> 4500) return 1; const memorando = new map (); const dp = (a, b) => {if (a <= 0 && b <= 0) retorna 0.5; if (a <= 0) retornar 1; if (b <= 0) return 0;
const key = `${a},${b}`;
if (memo.has(key)) return memo.get(key);
const result = 0.25 * (
dp(a – 4, b) +
dp(a – 3, b – 1) +
dp(a – 2, b – 2) +
dp(a – 1, b – 3)
);
memo.set(key, result);
return result;
};
const m = Math.ceil(n / 25);
return dp(m, m);
};
Enter fullscreen mode
Exit fullscreen mode
Python Version
import math
from functools import lru_cache
class Solution:
def soupServings(self, n: int) -> Float: se n> 4500: retornar 1,0 m = math.ceil (n / 25) @lru_cache (nenhum) def dp (a, b): se a <= 0 e b <= 0: retornar 0,5 se a <= 0: retornar 1,0 se b <= 0: retornar 0,0 0,0 0,25 * (dp (a – 4, b) + dp (dp (a 3: 3: 3: 3 0,0 0,0 0,25 * (dp (a – 4, b) + dp (dp (a 3: 3: 3: 3: 3 0,0 0,0 0,0 * (1 = 0: B). DP (a – 1, b – 3)) retorna dp (m, m) Digite a complexidade do tempo de tempo de saída do modo de tela cheia e complexidade do modo de tela cheia: o número de estados exclusivos que calculamos é proporcional a O (n^2), onde n é o número de unidades de 25 ml (ou seja, teto (N / 25)). Portanto, o pior dos casos é O (300 * 300) = 90.000 estados quando n = 4500. Complexidade do espaço: usamos uma matriz 2D ou tabela de memórias de tamanho o (n^2) para os resultados do cache. Pensamentos finais Este problema combina probabilidade e recursão. O principal insight é limitar o espaço do estado, agrupando quantidades de sopa em múltiplos de 25. Para N grande, a probabilidade de um terminado primeiro se torna tão próximo de 1,0 que podemos retornar com segurança 1 como uma aproximação. A memaçãoização ajuda a lidar com eficiência subproblemas sobrepostos sem recomputar.
Fonte
Publicar comentário