问题: 0/1背包问题
给定N个物品和一个背包,物品i的重量wi,价值vi,背包的容量为C。
思路:
令V(i,j)表示当前装入的i个物品的价值,j表示这i个物品的重量。因为不确定最优的情况下j的取值(只知道不大于题目要求的最大值C)。所以,分别按装1个,2个,。。。,N个物品,对j从0到C开始尝试装入。
设N=5, C=10, w[i]={2, 2, 6, 5, 4}, v[i] = {6, 3, 5, 4, 6};
举例如下:
程序实现:
#include <stdio.h>
#define N 5
#define C 10
int max(int a, int b)
{
if(a >= b)
return a;
else
return b;
}
int main(void)
{
int w[N + 1] = {0, 2, 2, 6, 5, 4};
int v[N + 1] = {0, 6, 3, 5, 4, 6};
int V[N+1][C+1] = {0};
int i = 0, j = 0;
int temp;
for (i = 0; i <= N; i++)
{
V[i][0] = 0;
}
for (j = 0; j <= C; j++)
{
V[0][i] = 0;
}
for (i = 1; i <= N; i++)
{
temp = w[i];
for (j = 1; j <= C; j++)
{
V[i][j] = V[i-1][j];
if (temp <= j)
{
V[i][j] = max((V[i][j]),(V[i-1][j-temp]+v[i]));
}
}
}
printf("\n装的最大值为:%d\n", V[N][C]);
for (i = 0; i <= N; i++)
{
printf("\n装%d件物品过程为: ", i);
for (j = 0; j <= C; j++)
{
printf(" %2d ", V[i][j]);
}
}
j = C;
printf("\n选中的物品为: ");
for (i = N; i > 0; i--)
{
if (V[i][j] > V[i-1][j])
{
printf(" %d ", i);
j = j - w[i];
}
}
printf("\n");
return 0;
}