您的位置:首页 > 其它

bone0-1背包问题

2016-05-12 20:48 246 查看
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

1
5 10
1 2 3 4 5
5 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
[v]<<endl;
    }

      return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: