bone0-1背包问题

来源:互联网 发布:谭浩强c语言ppt 编辑:程序博客网 时间:2024/06/05 09:10
Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like to collect varies of bones , such as dog’s , cow’s , also he went to the grave …<br>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 ?<br><center><img src=../../../data/images/C154-1003-1.jpg> </center><br>
 

Input
The first line contain a integer T , the number of cases.<br>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
One integer per line representing the maximum of the total value (this number will be less than 2<sup>31</sup>).
 

Sample Input
15 101 2 3 4 55 4 3 2 1
 

Sample Output

14

题意:经典的0-1背包问题,给你物品数目以及背包的容量,下面是各个物品的价值以及容量,让你求背包能装入的最大价值

状态方程 dp[i][j] = max(dp[i-1][j],dp[i-1][j-vol[i]]+val[i])

表达式中各个符号的具体含义。

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]}

“将前i 件物品放入容量为v的背包中”这个子问题,若只考虑第i 件物品的策略(放或不放),那么就可以转

化为一个只和前i-1件物品相关的问题。如果不放第i 件物品,那么问题就转化为“前i-1件物品放入容量为v的

背包中”,价值为F[i-1; v];如果放第i 件物品,那么问题就转化为“前i-1件物品放入剩下的容量为v-Ci 的

背包中”,此时能获得的最大价值就是F[i-1;v-Ci] 再加上通过放入第i 件物品获得的价值Wi。

#include<iostream>#include<cstring>using namespace std;int dp[1001][1001];//前i件物品放入j容量大的背包中的最大价值int f(int a,int b){    if(a>=b)        return a;    else        return b;}int main(){    int va[1001],vo[1001];    int k,n,v;    cin>>k;    while(k--)    {        memset(dp,0,sizeof(dp));//对其进行初始化        cin>>n>>v;        for(int i=1;i<=n;++i)        {            cin>>va[i];        }        for(int i=1;i<=n;++i)        {            cin>>vo[i];        }        for(int i=1;i<=n;++i)        {            for(int j=0;j<=v;++j)            {                if(j<vo[i])//第i个物品无法放入                    dp[i][j] = dp[i-1][j];                else                    dp[i][j] = f(dp[i-1][j],dp[i-1][j-vo[i]] + va[i]);//第i个物品放入后,看看是这个物品不放入大还是放入时大,因为他放入后,前i-1个物品可能放不进去            }        }        cout<<dp[n][v]<<endl;    }      return 0;}

0 0
原创粉丝点击