01背包问题具体例子:假设现有容量10kg的背包,另外有3个物品,分别为a1,a2,a3。物品a1重量为3kg,价值为4;物品a2重量为4kg,价值为5;物品a3重量为5kg,价值为6。将哪些物品放入背包可使得背包中的总价值最大?
这个问题有两种解法,动态规划和贪婪算法。本文仅涉及动态规划。
先不套用动态规划的具体定义,试着想,碰见这种题目,怎么解决?
首先想到的,一般是穷举法,一个一个地试,对于数目小的例子适用,如果容量增大,物品增多,这种方法就无用武之地了。
其次,可以先把价值最大的物体放入,这已经是贪婪算法的雏形了。如果不添加某些特定条件,结果未必可行。
最后,就是动态规划的思路了。先将原始问题一般化,欲求背包能够获得的总价值,即欲求前i个物体放入容量为m(kg)背包的最大价值c[i][m]——使用一个数组来存储最大价值,当m取10,i取3时,即原始问题了。而前i个物体放入容量为m(kg)的背包,又可以转化成前(i-1)个物体放入背包的问题。下面使用数学表达式描述它们两者之间的具体关系。
表达式中各个符号的具体含义。
w[i] : 第i个物体的重量;
p[i] : 第i个物体的价值;
c[i][m] : 前i个物体放入容量为m的背包的最大价值;
c[i-1][m] : 前i-1个物体放入容量为m的背包的最大价值;
c[i-1][m-w[i]] : 前i-1个物体放入容量为m-w[i]的背包的最大价值;
由此可得:
c[i][m]=max{c[i-1][m-w[i]]+pi , c[i-1][m]}(下图将给出更具体的解释)
根据上式,对物体个数及背包重量进行递推,列出一个表格(见下表),表格来自(http://blog.csdn.net/fg2006/article/details/6766384?reload) ,当逐步推出表中每个值的大小,那个最大价值就求出来了。推导过程中,注意一点,最好逐行而非逐列开始推导,先从编号为1的那一行,推出所有c[1][m]的值,再推编号为2的那行c[2][m]的大小。这样便于理解。
以上转载来自于:http://www.cnblogs.com/xy-kidult/archive/2013/03/25/2970313.html
Problem Description
The bone collector had a big bag with a volume of V ,and along his trip of collecting there are a lot of bones , obviously , different bone has different value and different volume, now given the each bone’s value along his trip , can you calculate out the maximum of the total value the bone collector can get ?
Input
Followed by T cases , each case three lines , the first line contain two integer N , V, (N <= 1000 , V <= 1000 )representing the number of bones and the volume of his bag. And the second line contain N integers representing the value of each bone. The third line contain N integers representing the volume of each bone.
Output
Sample Input
1 5 10 1 2 3 4 5 5 4 3 2 1
Sample Output
14
<span style="color:#333333;">#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
struct inin
{
int val;
int vol;
}boy[10010];
int main()
{
int T;
int sum;
int n,Vol;
int i,j;
int bag[10010];
scanf("%d",&T);
while(T--)
{
memset(boy,0,sizeof(boy));
memset(bag,0,sizeof(bag));
scanf("%d%d",&n,&Vol);
for(i=0;i<n;i++)
scanf("%d",&boy[i].val);
for(j=0;j<n;j++)
scanf("%d",&boy[j].vol);
for(i=0;i<n;i++)
{
for(j=Vol;j>=boy[i].vol;j--)
{
</span><span style="color:#cc0000;"> bag[j]=max(bag[j],bag[j-boy[i].vol]+boy[i].val);</span><span style="color:#333333;">
}
}
printf("%d\n",bag[Vol]);
}
return 0;
} </span>