Requisitos de tópico
Dê a você uma corda de comprimento n; por favor, corte a corda em m comprimentos de número inteiro (m e n são números inteiros, n> 1 e m> 1), o comprimento de cada corda é indicado como k [0], k [1], ..., k [m]. Qual é o produto máximo possível de k [0] xk [1] x ... xk [m]? Por exemplo, quando o comprimento da corda é 8, cortamos em três seções de comprimento 2, 3 e 3, respectivamente, e o produto máximo obtido nesse momento é 18.
1. Análise e solução de programação dinâmica
Primeiro, vamos dar uma olhada na programação dinâmica. Quais problemas gerais são resolvidos usando a programação dinâmica?
Se o problema procurar a solução ideal para um problema, e o problema puder ser decomposto em vários subproblemas, e há subproblemas menores que se sobrepõem.
Características:
- A solução ideal do problema geral é a solução ideal que depende de cada problema
- Divida os grandes problemas em vários pequenos e há sub-problemas menores que se sobrepõem
- Analise o problema de cima para baixo e resolva o problema de baixo para cima
Então, usando a idéia de programação dinâmica, vamos pensar em como cortar a corda.
Portanto, sabemos que f (1) = 1, f (2) = 1, f (3) = 2.
Armazenamos a solução ideal do subproblema nos produtos da matriz. O i-ésimo elemento da matriz representa o valor máximo do comprimento do produto de cada segmento após cortar o cabo de comprimento i em vários segmentos, ou seja, f (i)
.A implementação do código é a seguinte:
int maxproductAfterCutting(int length)
{
if (length < 2)
return 0;
if (length == 2)
return 1;
if (length == 3)
return 2;
int* products = new int[length + 1];
products[0] = 0;
products[1] = 1;
products[2] = 2;
products[3] = 3;
int max = 0;
for (int i = 4; i <= length; i++)
{
max = 0;
for (int j = 1; j < i / 2; j++)
{
int product = products[i] * products[i - j];
if (max < product)
max = product;
products[i] = max;
}
}
max = products[length];
delete[] products;
return max;
}
2. Algoritmo ganancioso
A idéia básica do algoritmo guloso é. Quando usamos o algoritmo ganancioso para resolver o problema, cada passo pode fazer uma escolha gananciosa.Com base nessa escolha, determinamos que podemos obter a solução ideal.
Quando n> = 5, cortamos o máximo possível da corda de comprimento 3. Quando o comprimento restante da corda é 4, cortamos a corda em dois comprimentos de corda.
int maxproductAfterCutting1(int length)
{
if (length < 2)
return 0;
if (length == 2)
return 1;
if (length == 3)
return 2;
//尽可能多的剪去长度为3的绳子段
int timeOf3 = length / 3;
//当绳子最后剩下的长度为4的时候,不能再剪去长度为3的绳子段
//此时更好的方法就是把绳子剪成长度为2的两段
if (length - timeOf3 * 3 == 1)
timeOf3 -= 1;
int timeOf2 = (length - timeOf3 * 3) / 2;
return (int)(pow(3, timeOf3)) * (int)(pow(2, timeOf2));
}
Então, por que escolher esse tipo de pensamento?
Quando n> = 5, podemos provar que 2 (n-2)> n e 3 (n-3)> n, ou seja, quando o comprimento da corda restante for maior ou igual a 5, iremos cortá-lo Em 3 ou 2 comprimentos de corda.
Quando n> 5, 3 (n-3)> = 2 (n-2), devemos cortar o maior número possível de comprimentos de corda.