【9405】背包问题
Time Limit: 10 second
Memory Limit: 2 MB
问题描述
简单的背包问题。设有一个背包,可以放入的重量为s。现有n件物品,重量分别为w1,w2.....wn(1≤i≤n),均为正整数,从n件物品中挑选若干件,使得放入背包的重量之和正好为s。找到一组解即可,如果不存在解,则输出“not found”。
Input
第一行是物品总件数和背包的载重量,第二行为各物品的重量。
Output
各所选物品的序号和重量。(定义输出物品较少的组合)
Sample Input
5 10 1 2 3 4 5
Sample Output
number:1 weight:1
number:4 weight:4
number:5 weight:5
【题解】
这是一个搜索问题。只要枚举每个物品是否在背包中即可。用sum变量来累加,如果sum > v则跳出搜索。因为要找最少物品数量,所以如果当前用掉的物品大于最小值也可以剪枝。当然你得先找到一组解,这个剪枝才有意义。
【代码】
#include <cstdio>
int n,v,a[20],sum = 0,min_n = 2100000000,b[20],ans[20]; //min_n在更新一组解之后变成一个剪枝的判断符
void input_data()
{
    scanf("%d %d",&n,&v);
    for (int i = 1;i <= n;i++)
        scanf("%d",&a[i]);
}
void sear_ch(int x,int num) //表示当前枚举到第x个物品,已经装了num个物品
{
    //可以加上一句 if num >= min_n return...
    if (sum > v) return; //如果超过了背包的容积则剪枝
    if (sum == v) //如果恰好等于容积 则尝试更新答案。 ans是记录答案的数组,b则是动态变化的。
        {
            if (num < min_n)
                {
                    min_n = num;
                    for (int i = 1;i <= b[0];i++)
                        ans[i] = b[i];
                }
            return;
        }
    if ( x > n)
        return;
    sum+=a[x]; //表示第x个物品要放进背包中
    b[0]++;
    b[b[0]] = x;
    sear_ch(x+1,num+1);
    b[0]--;
    sum-=a[x];
    sear_ch(x+1,num); //表示第x个物品不放进背包中。
}
void get_ans()
{
    sear_ch(1,0);
}
void output_ans()
{
    if (min_n == 2100000000) //记住是“==”,输出无解信息。
        {
            printf("not found");
            return;
        }
    for (int i = 1;i <= min_n;i++)
        printf("number:%d  weight:%d\n",ans[i],a[ans[i]]);
}
int main()
{
    //freopen("F:\\rush.txt","r",stdin);
    input_data();
    get_ans();
    output_ans();
    return 0;
}
 

                
            
        
浙公网安备 33010602011771号