01背包问题(回溯_子集树)

时限: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<stdio.h>
void readdata();
void search(int m);
void check_weight_maxvalue();
void print();

int n,contain;
int w[1000]={0},v[1000]={0};
int choice[1000]={0};
int weight=0,value=0,max_value=0;
int main()
{  
    readdata();
    while(n!=0&&contain!=0)
    {
        search(0);//子集树搜索模式进行搜索
        print();

        for(int i=0;i<1000;i++)
        { w[i]=0;  v[i]=0; choice[i]=0; };//每个物品重量
        weight=0,value=0,max_value=0;
        readdata();
    }
    return 0;
}
void readdata()
{
    int i;
    scanf("%d%d",&n,&contain);//n个物品,背包容量为contain
    for(i=0;i<n;i++)
        scanf("%d",&w[i]);//每个物品重量
    for(i=0;i<n;i++)
        scanf("%d",&v[i]);//每个物品价值
}
void search(int m)//子集树搜索模式
{
    if(m==n)  
        check_weight_maxvalue();
    else
    { 
        choice[m]=0;    search(m+1);
        choice[m]=1;    search(m+1);
    }
}
void check_weight_maxvalue()//检查是否在承载范围内,再刷新价值
{
    int i;
    for(i=0;i<n;i++)
        if(choice[i]==1)
        {
            weight+=w[i];
            value+=v[i];
        }
    if(weight<contain)
        if(value>max_value)
            max_value=value;
}
void print()
{
    printf("%d\n",max_value);
}
原文地址:https://www.cnblogs.com/IThaitian/p/2581747.html