Bone Collector 0-1背包问题

题目描述:

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 … 
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 ? 

输入:

The first line contain a integer T , the number of cases. 
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.

输出:

One integer per line representing the maximum of the total value (this number will be less than 2 31).

样例:

Sample Input

1
5 10
1 2 3 4 5
5 4 3 2 1

Sample Output

14
题目大意:
有一个人喜欢收集骨头(呃),现在有N根骨头,每根骨头对应着各自的体积和价值,这个人的背包容量为V,求能装的骨头的最大总价值。
代码:
#include
#include
#define max(a,b) a>b?a:b
struct bone{
    int wei,val;
};
int f[1002][1002];
bone temp[1005];
int value(int num,int v){
    for(int i=1;i<=num;++i){
        for(int j=0;j<=v;++j){
            if(j1].wei)
                f[i][j]=f[i-1][j];
            else
                f[i][j]=max(f[i-1][j-temp[i-1].wei]+temp[i-1].val,f[i-1][j]);
        }
    }
    return f[num][v];
}
using namespace std;
int main(){
    int n,num,v;
    scanf("%d",&n);
    for(int i=0;ii){
        scanf("%d%d",&num,&v);
        for(int j=0;j"%d",&temp[j].val);
        for(int j=0;j"%d",&temp[j].wei);
        printf("%d\n",value(num,v));
    }
    return 0;
}

这是一道0-1背包问题,要解决的问题就是要放哪些物品进背包,总价值是多少。

而对于每一个物品只有放与不放两种情况:

1. 第i件放进去:价值为:f[i-1][v-temp[i-1].wei]+temp[i-1].val(背包容量减去第i件物品的体积,再加上对前i-1件进行判断后得到价值的最大值(容量为v-temp[i-1].wei的背包))

2. 第i件不放进去:价值为:f[i-1][v](容量不减少(为v),对前i-1件进行判断后得到价值的最大值)

状态转移方程为:f[i][v] = max(f[i-1][v], f[i-1][v-w[i]]+c[i])

随后对两种情况取较大值。第一行初始化为0.从第一个物品开始列表记录背包容量内剩余不同容积存放前i个物品情况的最大值。

这个解法比较容易理解,下面的链接有对背包问题更详尽的解释,受启发于此:

https://www.cnblogs.com/A-S-KirigiriKyoko/p/6036368.html

https://www.cnblogs.com/xym4869/p/8513801.html

(其中的代码将第一列也初始化为0,这样子的话当物品中同时存在体积=背包容量的物品和体积=0的物品时就会出错,因此稍作改动)

你可能感兴趣的:(Bone Collector 0-1背包问题)