例题介绍
商店里有五件物品
来了一个小偷他的背包最多可以装下W=20的物品
B(k,w)
B表示能偷得的最高价格
k为前k个物品
w为剩下多少空间
基本递归公式
(核心)
以此类推 直到不能偷以不偷一条路向下
即
CanStealItem | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
没有物品 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
价值3重量2 | 0 | 0 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 |
价值4重量3 | 0 | 0 | 3 | 4 | 4 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 |
价值5重量4 | 0 | 0 | 3 | 4 | 5 | 7 | 8 | 9 | 9 | 12 | 12 | 12 | 12 | 12 | 12 | 12 | 12 | 12 | 12 | 12 | 12 |
价值8重量5 | 0 | 0 | 3 | 4 | 5 | 8 | 8 | 11 | 12 | 13 | 15 | 16 | 17 | 17 | 20 | 20 | 20 | 20 | 20 | 20 | 20 |
价值10重量9 | 0 | 0 | 3 | 4 | 5 | 8 | 8 | 11 | 12 | 13 | 15 | 16 | 17 | 17 | 20 | 20 | 21 | 22 | 23 | 25 | 26 |
对B(1,2)求
整个算法的基本思路与公式挂钩
代码实现如下
#include<stdio.h>
#define N 6
#define W 21
int B[N][W]={0};
int w[6]={0,2,3,4,5,9};
int v[6]={0,3,4,5,8,10};
void knapsack()
{
int k,C;
for(k=1;k<N;k++)
{
for(C=1;C<W;C++)
{
if(w[k]>C)
{
B[k][C]=B[k-1][C];
}
else
{
int value1=B[k-1][C-w[k]]+v[k];
int value2=B[k-1][C];
if(value1>value2)
{
B[k][C]=value1;
}
else
{
B[k][C]=value2;
}
}
}
}
}
int main()
{
knapsack();
printf("%d\n",B[5][20]);
return 0;
}