Não vou entrar em detalhes sobre a ideia de programação dinâmica aqui, se precisar entendê-la, leia este artigo Etapas de planejamento dinâmico
Vamos direto ao assunto e usar ideias de programação dinâmica para resolver 343. Divisão de números inteiros - LeetCode .
O primeiro passo é determinar o array dp e criar um array que armazene o produto máximo obtido após a divisão dos inteiros.
# 确定数组的长度,每次拆分的计算结果是为上一次的最大乘积,作为占位符。
dp = [0] * (n+1)
A segunda etapa é determinar o valor inicial do array dp.
Podemos saber pela pergunta que não faz sentido dividir n == 0 ou n == 1. Obviamente, quando dividimos n == 2, podemos obter 2 = 1 + 1, então o produto máximo é 1, ou seja , dp[2] = 1, e os resultados do produto calculados subsequentes também são baseados nos resultados de dp[2].
dp[2] = 1
A terceira etapa é determinar a equação de transição de estado. dp[i] = max(dp[i], j * (ij), j * dp[i - j])
Podemos explicar isso através de um exemplo simples: quando n = 5, o array dp armazena o valor do produto máximo obtido pela divisão de cada inteiro.
Existem várias questões que precisam ser observadas:
1. Problema de divisão: Precisamos dividir um inteiro para que a adição de dois ou mais inteiros seja igual ao número original e o produto dos valores de divisão seja o maior. Portanto, precisamos considerar a divisão de dois números inteiros positivos e depois dividi-los ou não.
1) Divida i na soma de j e i−j, e i−j não será mais dividido em vários inteiros positivos. O produto neste momento é j * (ij)
2) Divida i na soma de j e i − j e continue a dividir i − j em vários inteiros positivos. O produto neste momento é j * dp[ij]. Neste momento, precisamos do valor anterior no o valor da matriz dp é chamado.
2. j começa a percorrer a partir de 1. ij pode ser entendido como a subtração do valor de passagem correspondente de j do valor de n que precisa ser dividido.
j * (i - j) é o produto da divisão de dois inteiros.
3. Precisamos comparar o máximo do produto de j * (i - j) e j * dp[ij].
Portanto, a equação de transição de estado é: dp[i] = dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));
for i in range(3, n + 1):
for j in range(1, i - 1):
dp[i] = max(dp[i], max(j * (i - j), j * dp[i - j]))
A quarta etapa é determinar a ordem de passagem.
dp[i] depende do estado de dp[i - j], portanto, a travessia i deve ser percorrida de frente para trás. i começa em 3 e, ao enumerar j, começa em 1. Desta forma, dp[i - j] é dp[2], que pode ser calculado pelo valor que inicializamos.
A quinta etapa, usando n = 5 como exemplo, pode ser deduzida através da tabela acima.
exibição do código python:
def integerBreak(n):
dp = [0] * (n + 1)
dp[2] = 1
for i in range(3, n + 1):
for j in range(1, i - 1):
dp[i] = max(dp[i], max(j * (i - j), j * dp[i - j]))
return dp[n]
print(integerBreak(5))