1. Descripción general del problema de las mochilas
Como se muestra en la imagen, solo hay una diferencia entre la mochila completa y la mochila 01: solo puedes llevar un artículo de cada artículo en la mochila 01, pero puedes llevar innumerables artículos de cada artículo en la mochila completa. Para resolver el problema completo de la mochila, primero debes comprender la mochila 01. Si no lo tienes claro, puedes leer mi artículo 01 mochila: programación dinámica .
2. Preguntas de ejemplo
peso | valor | |
---|---|---|
Artículo 0 | 1 | 15 |
Artículo 1 | 3 | 20 |
Artículo 2 | 4 | 30 |
La capacidad máxima de la mochila es 4.
Cada artículo tiene dos estados: "tomar" o "no tomar". El método de retroceso se puede utilizar para enumerar violentamente las permutaciones y combinaciones del estado de todos los elementos y compararlo con la capacidad máxima de la mochila para encontrar el valor máximo. La complejidad del tiempo es O (2 n) O (2 ^ n) . )O ( 2n )está en nivel exponencial, por lo que se requiere una solución de programación dinámica para la optimización.
3. Solución de matriz unidimensional (matriz rodante) para completar la mochila
1. De 01 mochila a mochila completa
De 01 Knapsack - Programación dinámica , podemos saber que una matriz DP unidimensional es una simplificación de una matriz DP bidimensional. Por lo tanto, la matriz DP bidimensional es esencialmente la misma que la matriz DP unidimensional. Este artículo solo presenta la solución de matriz DP unidimensional a la mochila completa.
Para la mochila 01, el bucle interior j
se recorre hacia atrás de grande a pequeño, la razón es para evitar que dp[j]
los elementos anteriores se contaminen y evitar el problema de acumulación (cada artículo solo se puede seleccionar una vez). Para una mochila completa, cada artículo se puede seleccionar innumerables veces. j
Atravesar de adelante hacia atrás significa j
intentar colocar artículos en cada capacidad i
para ver si aumentará el valor total. No presta atención a i
la cantidad de artículos colocados. Por tanto, solo existe una diferencia entre el código de la mochila completa y la mochila 01, que es j
el orden de recorrido.
// 01背包遍历
for(int i = 0; i < weight.size(); i++) {
// 遍历物品
for(int j = bagWeight; j >= weight[i]; j--) {
// 遍历背包容量
dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
}
}
// 完全背包遍历
// 先遍历物品,再遍历背包
for(int i = 0; i < weight.size(); i++) {
// 遍历物品
for(int j = weight[i]; j <= bagWeight ; j++) {
// 遍历背包容量
dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
}
}
2. La diferencia entre mochila 01 y mochila completa: orden transversal
El orden de recorrido de 01 mochila es:
En la matriz DP bidimensional, puede recorrer primero los elementos o la capacidad de la mochila;
En una matriz DP unidimensional, los elementos deben atravesarse primero antes de atravesar la capacidad de la mochila. Sólo de esta manera podrá asegurarse de que cada elemento se seleccione solo una vez.
Para una mochila completa, no hay restricción de que solo pueda seleccionarla una vez, entonces, ¿está bien recorrer primero la capacidad de la mochila y luego recorrer los elementos? La respuesta es sí. Porque se calcula en función del elemento de la matriz DP correspondiente al dp[j]
subíndice . j
Solo asegúrese de que j
se calcule la matriz DP antes del subíndice. La Figura 1 atraviesa primero la capacidad de la mochila y luego los artículos; la Figura 2 atraviesa primero los artículos y luego atraviesa la capacidad de la mochila.
// 先遍历物品,再遍历背包
for(int i = 0; i < weight.size(); i++) {
// 遍历物品
for(int j = weight[i]; j <= bagWeight ; j++) {
// 遍历背包容量
dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
}
}
// 先遍历背包,再遍历物品
for(int j = 0; j <= bagWeight; j++) {
// 遍历背包容量
for(int i = 0; i < weight.size(); i++) {
// 遍历物品
if (j - weight[i] >= 0)
dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
}
}