Algoritmo clásico de programación dinámica (problema de mochila)

Pregunta: Actualmente hay cuatro elementos, la capacidad total de la mochila es 8, cuál es el valor máximo que puede contener la mochila

Número de artículo: 1 2 3 4

Volumen del artículo: 2 3 4 5

Valor del artículo: 3 4 5 6

Número \ Capacidad 0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 3 3 3 3 3 3 3
2 0 0 3 4 4 7 7 7 7
3 0 0 3 4 5 7 8 9 9
4 0 0 3 4 5 7 8 9  

Ideas para cumplimentar el formulario:

  1. Si el elemento actual no se puede cargar, la mejor combinación de los primeros n elementos es la misma que la mejor combinación de los primeros n-1 elementos.
  2. Puede cargar el artículo actual
    1. Cargue el artículo actual, reserve el espacio correspondiente para el artículo actual en la mochila, la mejor combinación de los primeros n-1 artículos más el valor del artículo actual, es el valor total
    2. Si el el elemento actual no está cargado, entonces el anterior La mejor combinación de n elementos es la misma que la mejor combinación de los primeros n-1 elementos
    3. Seleccione el valor más grande de 1 y 2 como el valor de la mejor combinación actual

Volviendo al problema de la mochila:
en el caso de maximizar el valor total de la mochila, qué elementos están contenidos en la mochila

Análisis: El valor actual es 10. Si el elemento 4 no está instalado, entonces el valor actual (10) debe ser el mismo que el valor total de los primeros tres elementos (9). Obviamente, el 10 y el 9 son diferentes, por lo que se incluyó el elemento 4.

Resumen: Mirando hacia atrás de atrás hacia adelante, si el valor de la mejor combinación de los primeros n elementos es el mismo que el valor de la mejor combinación de los primeros n-1 elementos, significa que el n-ésimo elemento no se ha cargado en la mochila. De lo contrario, se carga en una mochila.

Código

// Dynamic programming

/* 物品编号  1   2   3   4
   体积     2   3   4   5
   价值     3   4   5   6*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int weight[5] = {0, 2, 3, 4, 5};
int value[5] = {0, 3, 4, 5, 6};
int dp[5][9] = {0};
int object[5];

int max(int x, int y){
    return x>y?x:y;
}

void printDp() {
    
    for(int i=0;i<5;i++) {
        for (int j=0; j<9; j++) {
            printf("%d\t",dp[i][j]);
        }
        printf("\n");
    }
        
}

int dpWrite() {

    memset(dp,0,sizeof(dp));
    for (size_t i = 1; i < 5; i++) //物品编号
    {
        for (size_t j = 1; j < 9; j++) // 背包容量
        {
            if(weight[i]>j) //物品放不下
                dp[i][j] = dp[i-1][j]; 
            else
                dp[i][j]= max(dp[i-1][j], value[i] + dp[i-1][j-weight[i]]);
        }
        
    }
    printDp();
}

// 背包回溯问题
void Find(int i, int j) {
    if (i == 0) {
        for (int ii=0; ii<5; ii++) {
            printf("%d ",object[ii]);
        }
        return;
    }
    // 没装入背包
    if (dp[i][j] == dp[i - 1][j]) {
        object[i] = 0;
        Find(i-1, j);
    }
    // 装入背包
    else if (dp[i][j] == value[i] + dp[i - 1][j - weight[i]]) {
        object[i] = 1;
        Find(i-1, j-weight[i]);
    }
}

int main() {
    dpWrite();
    Find(4, 8);
    printf("\n(%d, %d)===>[",4, 8);
    for (int i=0; i<5; ++i) {
        printf("%d ", object[i]);
    }
    printf("]\n");
}

 

Supongo que te gusta

Origin blog.csdn.net/weixin_44937328/article/details/115350692
Recomendado
Clasificación