0-1背包问题(回溯+暴力)

来源:互联网 发布:windows xp vol key 编辑:程序博客网 时间:2024/06/08 19:47

背包问题是算法中的经典问题,可以用许多种方法来求解。


一、基于暴力搜索的背包求解。

 假设有n个物体,价值和重量分别用vi和wi来表示,用暴力搜索,我们将最终的解用一个向量来表示,因此所有的解空间可以用00...00到11...11来表示。而这些数恰对应0至2^n-1的二进制转换。因此可以基于该思想,利用二进制转换进行暴力搜索。

#include <stdio.h>  #include <math.h>    int main()  {      int num,maxv=0;      int n, c, *w, *v, tempw, tempv;      int i,j,k;        printf("input the number and the volume:");      scanf("%d%d",&n,&c);            w=new int [n];      v=new int [n];          printf("input the weights:");      for(i=0;i<n;i++)          scanf("%d",&w[i]);        printf("input the values:");      for(i=0;i<n;i++)          scanf("%d",&v[i]);        for(num=0;num<pow(2,n);num++) //每一个num对应一个解      {          k=num; tempw=tempv=0;             for(i=0;i<n;i++) //n位二进制          {              if(k%2==1){     //如果相应的位等于1,则代表物体放进去,如果是0,就不用放了                  tempw+=w[i];                  tempv+=v[i];              }              k=k/2;          //二进制转换的规则          }          //循环结束后,一个解空间生成,          //判断是否超过了背包的容积,          //如果没有超,判断当前解是否比最优解更好          if(tempw<=c){              if(tempv>maxv)                  maxv=tempv;          }      }        printf("the result is %d.\n",maxv);        return 0;     }  

二、基于回溯法的背包求解。

#include<stdio.h>#define n 3#define c 30int weight[n]={16,15,15};int value[n]={45,25,25};int tempvalue=0;int maxvalue=0;int totalvalue=0;int tempweight=0;void traceback(int t){if(t==n){if(tempvalue>maxvalue)    maxvalue = tempvalue;    return ;}if(t==0){for(int i=0;i<n;i++){    totalvalue+=value[i];    }}if(tempweight+weight[t]<=c&&tempvalue+totalvalue>maxvalue){  //当背包中已有的重量加上该物品后
                // 重量不大于承重而且背包中已有的价值加上还未装入的所有的价值大于之前已经找到的最大值                                                            tempweight+=weight[t];                                    tempvalue+=value[t];totalvalue-=value[t];traceback(t+1);tempweight-=weight[t];tempvalue-=value[t];totalvalue+=value[t];}traceback(t+1);}int main(){traceback(0);printf("%d\n",maxvalue); return 0;}


原创粉丝点击