算法设计与分析——0/1背包问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_28666193/article/details/53352243

【问题描述】

给定n个重量为{w1,w2,...wn},价值为{v1,v2,...,vn}的物品和一个容量为C的背包,0、1背包问题是求这些物品中的一个
最有价值的子集,并且能够装入背包中。

【基本算法思想】

暴力法:
用暴力法解决0、1背包问题,需要考虑给定n个物品集合的所有子集,找出所有重量不超过背包重量的子集,计算其每个子集的
总价值,比较输出价值最大的那个子集。

复杂度分析: 一个具有n个元素的集合,其子集数量为2的n次方,暴力法全集遍历时,其复杂度为O(2的n次方)。

【源代码】

//0-1背包问题c++语言实现
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
int main(){
    int num,C,i,j,k,len;
    int maxValue=0,sumWeight,sumValue;
    int w[10],v[10],temp[10],res[10];
    char a[10];
    cout<<"输入容量和物品个数:\n";
    cin>>C>>num;
    cout<<"输入重量和价值:\n";
    for(i=0;i<num;i++)
        cin>>w[i]>>v[i];
    for(i=0;i<pow(2,num);i++){          //遍历所有子集
        sumWeight=0;
        sumValue=0;
        itoa(i,a,2);                //将每一趟可能值用二进制匹配
        len=strlen(a);
        memset(temp,0,sizeof(int)*num);         //将辅助数组置为0
        for(j=len-1,k=0;j>=0;j--){              //k为辅助数组的下标,每一外层循环时置为0
            if(a[j]=='1'){
                sumWeight+=w[num-len+j];
                sumValue+=v[num-len+j];
                temp[k++]=w[num-len+j];
            }
        }
        if(sumWeight<=C&&sumValue>maxValue){
            maxValue=sumValue;
            memset(res,0,sizeof(int)*num);      //更新结果集
            memcpy(res,temp,sizeof(int)*num);
        }
    }
    cout<<"\n取重量为下列的子集:\n";             //输出结果
    for(i=0;i<k;i++)
        if(res[i])cout<<res[i]<<"  ";
    cout<<"\n最大价值为:"<<maxValue;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_28666193/article/details/53352243