0-1背包问题

来源:互联网 发布:java工程师证书有用吗 编辑:程序博客网 时间:2024/05/17 01:03

0-1背包问题

时限:1000ms 内存限制:10000K  总时限:3000ms

描述
需对容量为c 的背包进行装载。从n 个物品中选取装入背包的物品,每件物品i 的重量为wi ,价值为pi 。对于可行的背包装载,背包中物品的总重量不能超过背包的容量,最佳装载是指所装入的物品价值最高。
 
输入
多个测例,每个测例的输入占三行。第一行两个整数:n(n<=10)和c,第二行n个整数分别是w1到wn,第三行n个整数分别是p1到pn。
n 和 c 都等于零标志输入结束。
 
输出
每个测例的输出占一行,输出一个整数,即最佳装载的总价值。
 
输入样例
1 2
1
1
2 3
2 2
3 4
0 0
 
输出样例
1
4

 





#include <iostream>#include <algorithm>using namespace std;double c;       //背包容量int n;          //物品数double cw;      //当前重量double cp;      //当前价值int bestp;   //当前最优价值typedef struct Item{    double w;   //物品的重量    double p;   //物品的价值}Item;Item item[100];bool cmp(Item a, Item b){    return a.p/a.w > b.p/b.w;}double bound(int i){    double cleft = c - cw;     //剩余容量    double b = cp;             //能装载容量的最大上界    //将剩余物品装入背包,直至装不下为止    while(i <= n && item[i].w <= cleft)    {        cleft -= item[i].w;        b += item[i].p;    }    //将最后一件装不下的物品拆解,让背包装满    //计算能装载容量的最大上界    if(i <= n)        b += item[i].p/item[i].w*cleft;    return b;}void Backtrack(int i){    //叶子节点    if(i > n)    {        if(cp > bestp)              //上界不一定取到                        bestp = (int)cp;                return;    }    //搜索子树    if(cw + item[i].w <= c)    {        cw += item[i].w;        cp += item[i].p;        Backtrack(i+1);        cw -= item[i].w;        cp -= item[i].p;    }    if(bound(i+1) > bestp)        Backtrack(i+1);}int main(){    while(cin >> n >> c && (n || c))    {        bestp = 0;                      //每组样例初始化        for(int i = 1; i <= n; i ++)    //i从1开始            cin >> item[i].w;        for(int i = 1; i <= n; i ++)            cin >> item[i].p;        sort(item+1, item+n+1, cmp);    //从1开始,wa了好多次        Backtrack(1);                  //从1开始递归        printf("%d\n", bestp);    }    return 0;}


0 0