思路:
设value_get[i][j]为把前i个物品装入容量为j的背包所能获得的最大价值
需考虑能否装入物品i,以及是否装入物品i,递归式为:
value_get[i][j] = max{ value_get[i-1][j], value_get[i-1][ j-weight[i] ] + value[i] }
c语言代码如下:
/*************************************************************************
> File Name: knapsack_dynamic.c
> Author: arui
> Mail: 450252722@qq.com
> Created Time: Wed 26 Feb 2014 01:43:14 PM CST
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
int knapsack_dynamic(int capacity,
int *weight,
int *value,
int *choice,
int obj_num)
{
int ** value_get = (int**)malloc(sizeof(int*) * (obj_num + 1));
for(int i = 0; i <= obj_num; ++i)
{
value_get[i] = (int*)malloc(sizeof(int) * (capacity + 1));
}
//initialize
for(int j = 0; j <= capacity; ++j)
{
value_get[0][j] = 0;
}
for(int i = 0; i <= obj_num; ++i)
{
value_get[i][0] = 0;
}
for(int i=1; i <= obj_num; ++i)
{
for(int j=1; j <= capacity; ++j)
{
value_get[i][j] = value_get[i-1][j];
if(weight[i] <= j)
{
int temp_value = value_get[i-1][j-weight[i]] + value[i];
if(temp_value > value_get[i][j])
value_get[i][j] = temp_value;
}
}
}
//construct the choice
int j = capacity;
for(int i = obj_num; i > 0; --i)
{
if(value_get[i][j] > value_get[i-1][j])
{
choice[i] = 1;
j = j - weight[i];
}
}
//free the space
for(int i = 0; i <= obj_num; ++i)
{
free(value_get[i]);
}
free(value_get);
return value_get[obj_num][capacity];
}
int main(int argc, char** argv)
{
int *weight;
int *value;
int *choice;
int capacity;
int obj_num;
freopen("test.dat","r", stdin);
while(scanf("%d%d",&capacity, &obj_num) != EOF)
{
weight = (int*)malloc((obj_num + 1) * sizeof(int));
value = (int*)malloc((obj_num + 1) * sizeof(int));
choice = (int*)malloc((obj_num + 1) * sizeof(int));
for(int i = 1; i <= obj_num; ++i)
{
scanf("%d", weight + i);
}
for(int i = 1; i <= obj_num; ++i)
{
scanf("%d", value + i);
}
int max_value = knapsack_dynamic(capacity,
weight, value, choice, obj_num);
printf("max_value = %d\n", max_value);
for(int i = 1; i <= obj_num; ++i)
{
printf("%d", choice[i]);
}
printf("\n");
//free the space
free(weight);
free(value);
free(choice);
}
return 0;
}