用自己的话解读一下这个问题。
借鉴了两篇文章
https://my.oschina.net/llmm/blog/117421
http://blog.youkuaiyun.com/mu399/article/details/7722810
01背包问题就是在有限的空间里面得到最大价值
有动态方程 f[i,j] = Max{ f[i-1,j-Wi]+Pi( j >= Wi ), f[i-1,j] }
意思是,当要放入第i个物品时,最大价值取决于2个方案的选择
1、加入第i个物品,f[i,j] 等于 加入i之前的最大值 f[i-1,j-Wi] ,加上i的价值Pi(Wi为i的重量)
2、不加入第i个物品,f[i,j] 等于 不加入i之前的最大值f[i-1,j]
结果取1、2中最大值。这是一个递归问题。
题目:
有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?
name | weight | value |
a | 2 | 6 |
b | 2 | 3 |
c | 6 | 5 |
d | 5 | 4 |
e | 4 | 6 |
当i = 0时,可以选择a,b,c,d,e,当i= 1时,可以选择b,c,d,e,当i= 4时,只能选择e
当i = 4时,背包重量从1到10,结果为
name | weight | value | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
e | 4 | 6 | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 6 | 6 |
当i = 3 时,可以有e,d两个物品选择。bagsize小于4,放不了东西,最大值为0,当bagsize=5时,
有d,e两个物品可以2选1。调用动态方程f (3,5)=
1、放入d,f(i-1,j-Wi)+Pi = f (4,5-5) + 4 , f(4,0) = 0, 则放入d的最大值为4
2、不放入d,f(i-1,j) = f(4,5) = 6
方案2>方案1
同理可以得到
name | weight | value | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
a | 2 | 6 | 0 | 6 | 6 | 9 | 9 | 12 | 12 | 15 | 15 | 15 |
b | 2 | 3 | 0 | 3 | 3 | 6 | 6 | 9 | 9 | 9 | 10 | 11 |
c | 6 | 5 | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 10 | 11 |
d | 5 | 4 | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 10 | 10 |
e | 4 | 6 | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 6 | 6 |
#include <stdio.h>
int get_value(int i,int bagsize);
int goods_w[5] = {2,2,6,5,4};
int goods_v[5] = {6,3,5,4,6};
int get_value(int i, int bagsize)
{
if (i > 4)
{
return 0;
}
int a = get_value(i+1,bagsize);
int b = 0;
if (bagsize >= goods_w[i])
{
b = get_value(i+1,bagsize-goods_w[i])+ goods_v[i];
}
return a>b?a:b;
}
int main()
{
for(int i = 1;i<=10;i++)
{
printf("bagsize is :%d\n",i);
for (int j =0;j<=4;j++)
{
int x = get_value(j,i);
printf("max:%d\n",x);
}
}
return 0;
}