Sie sind auf Seite 1von 5

PROBLEMA DEL CORTE DE LA VARILLA

Enunciado:
Dada una varilla de longitud n y una lista de precios de la varilla de longitud i donde 1 <= i
<= n, encuentre la forma óptima de cortar la varilla en barras más pequeñas para maximizar
el beneficio.
Por ejemplo, consideremos debajo las longitudes y valores de la barra. (Longitud de la
barra=4)

Longitud 1 2 3 4 5 6 7 8
Precio 1 5 8 9 10 16 17 20

------------------------------------------------------------------------------------------------------------------------
Análisis de cortes:
¿De cuantas formas distintas podemos cortar una varilla de longitud n? Rpta: 2n-1
Ej. n=4

 Hay n-1 posiciones de corte, y se debe escoger 0 ≤ 𝑘 ≤ 𝑛 − 1 cortes

𝑛−1
൬ ൰
𝑘

a) b) c) d)

e) f) g) h)

 Con 0 cortes
3 3!
൬ ൰= =1
0 0! 3!

a) b) c) d)

e) f) g) h)
 Con 1 corte 3 3!
൬ ൰= =3
1 1! 2!

a) b) c) d)

e) f) g) h)

 Con 2 cortes
3 3!
൬ ൰= =3
2 2! 1!

a) b) c) d)

e) f) g) h)

 Con 3 cortes
3 3!
൬ ൰= =1
3 3! 0!

a) b) c) d)

e) f) g) h)

𝑛−1 𝑛−1
𝑛−1 ሺ𝑛 − 1ሻ!
෍൬ ൰= ෍ = 2𝑛 −1
𝑘 𝑘! ሺ𝑛 − 1 − 𝑘ሻ!
𝑘=0 𝑘=0

------------------------------------------------------------------------------------------------------------------------
PRIMERA FORMA DE SOLUCION
El mejor corte para la varilla es de dos piezas de longitud 2 para obtener el mejor ingreso
económico seria de 10 de acuerdo a la siguiente tabla.
Corte Beneficio
4 9
1,3 1+8=9
2,2 5+5=10
3,1 8+1=9
1,1,2 1+1+5=7
1,2,1 1+5+1=7
2,1,1 5+1+1=7
1,1,1,1 1+1+1+1=4

La idea es simple. Uno por uno dividimos la barra dada de longitud n en dos partes de
longitud i y n-1 ((1, n-1), (2, n-2), (3, n-3) …); y tomamos el máximo de todos los valores.
Esto produce la siguiente relación recursiva:
rodCut(n) = max {precio[i-1] + rodCut(n-1)} donde 1<=i<=n

 La implementación en Java seria:

class Main
{
// Function to find best way to cut a rod of length n
// where rod of length i has a cost price[i-1]
public static int rodCut(int[] price, int n)
{
// base case
if (n == 0) {
return 0;
}

int maxValue = Integer.MIN_VALUE;

// one by one partition the given rod of length n into


// two parts of length (1, n-1), (2, n-2), (3, n-3), ....
// (n-1, 1), (n, 0) and take maximum
for (int i = 1; i <= n; i++)
{
// rod of length i has a cost price[i-1]
int cost = price[i - 1] + rodCut(price, n - i);

if (cost > maxValue) {


maxValue = cost;
}
}
return maxValue;
}

public static void main(String[] args)


{
// length[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
int price [] = { 1, 5, 8, 9, 10, 17, 17, 20 };

// rod length
int n = 4;

System.out.println("Profit is " + rodCut(price, n));


}
}

La complejidad temporal de la solución anterior es O(nn) y el espacio auxiliar utilizado por


el programa es O(1).
Lo llamamos subestructura óptima porque el problema de puede dividir en subproblemas
más pequeños que se pueden dividir en subproblemas aún más pequeños, y así
sucesivamente. Consideremos el árbol de recursión para la varilla de longitud 4:

Como se ve, los mismos subproblemas resaltados se calculan una y otra vez; entonces el
problema exhibe subproblemas superpuestos y como se sabe los problemas que tengan
una óptima subestructura y subproblemas superpuestos se pueden resolver mediante
programación dinámica, en la que las soluciones son subproblemas memorizados en lugar
de calcularse una y otra vez.

SEGUNDA FORMA DE SOLUCION


Otra forma seria de forma ascendente, primero resolvemos subproblemas más pequeños y
luego los subproblemas más grandes; el enfoque ascendente calcula T[i], que almacena la
ganancia máxima obtenida de la barra de longitud i para cada 1<=i<=n.

La implementación sería la siguiente:

class Main2
{
// Function to find best way to cut a rod of length n
// where rod of length i has a cost price[i-1]
public static int rodCut(int[] price, int n)
{
// T[i] stores maximum profit achieved from rod of length i
int[] T = new int[n + 1];

// consider rod of length i


for (int i = 1; i <= n; i++)
{
// divide the rod of length i into two rods of length j
// and i-j each and take maximum
for (int j = 1; j <= i; j++) {
T[i] = Integer.max(T[i], price[j - 1] + T[i - j]);
}
}

// T[n] stores maximum profit achieved from rod of length n


return T[n];
}

public static void main(String[] args)


{
// int[] length = { 1, 2, 3, 4, 5, 6, 7, 8 };
int[] price = { 1, 5, 8, 9, 10, 17, 17, 20 };
int n = 4; // rod length

System.out.print("Profit is " + rodCut(price, n));


}
}

La complejidad temporal de esta solución es O(n2) y el espacio auxiliar utilizado por el


programa es O(n).

Das könnte Ihnen auch gefallen