zoukankan      html  css  js  c++  java
  • 0-1背包回溯

    限定条件:

    如果放入该物品<剩余背包容量则回溯。

    如果当前价值+剩余容量下剩余物品的最大价值<当前最大价值则回溯。(剩下在怎么放都不会比当前最大价值大,就没必要算了)

    测试:

    第一行分别输入物品数量n与背包容量c

    用例:

    10 300
    95 89
    75 59
    23 19
    73 43
    50 100
    22 72
    6 44
    57 16
    89 7
    98 64

    测试结果:

    388

    代码:

     1 /*测试用例结果388 
     2 10 300
     3 95 89
     4 75 59
     5 23 19
     6 73 43
     7 50 100
     8 22 72
     9 6 44
    10 57 16
    11 89 7
    12 98 64
    13 */ 
    14 #include<stdio.h>
    15 #include<stdlib.h>
    16 int n,c;//物品数量,背包容量 
    17 int w[300],v[300]; //物品重量,物品价值。 
    18 float u[300][2];
    19 float U[300];//物品单位价值。 
    20 int max = 0; //当前最大价值 
    21 int num = 0;//递归次数 
    22 int cmp(const void *a,const void *b){//排序从大到小 
    23     return ((float*)a)[1]>((float*)b)[1]?-1:1;
    24 }
    25 float f1(int i,int weight);//返回剩余最大价值 
    26 void f(int i,int weight,int val);//求最大价值 
    27 int main(){
    28     scanf("%d %d",&n,&c);
    29     int w1[300],v1[300];
    30     for(int i=0;i<n;i++){//输入每个物品质量与价值 
    31         scanf("%d",&w1[i]);
    32         scanf("%d",&v1[i]);
    33     }
    34     for(int i=0;i<n;i++){//获得单位价值 
    35         u[i][0] = i;
    36         u[i][1] = (float)v1[i]/w1[i];
    37     }
    38     qsort(u,n,sizeof(u[0]),cmp);//单位价值排序 
    39     for(int i=0;i<n;i++){//排序物品 
    40         w[i] = w1[(int)u[i][0]];
    41         v[i] = v1[(int)u[i][0]];
    42         U[i] =  u[i][1];
    43     }
    44     f(0,0,0);
    45     printf("%d
    ",max);
    46     printf("递归次数:%d",num);
    47 }
    48 void f(int i,int weight,int val){//i表示第i个物品,weight表示当前重量,val表示当前价值。 
    49     num++;
    50     if(i==n){//判断到第n个物品 
    51         if(weight<=c) max = max>val?max:val;//返回当前价值和最大价值的最大者。 
    52         return;
    53     }
    54     //右子树的进入条件 即放入当前物品 
    55     //if(weight+w[i]<=c&&f1(i,c-weight)+val>max)//当剩余背包容量不足,或者当前价值+当前剩余最大价值<当前最大值,减去右子树。 
    56         f(i+1,weight+w[i],val+v[i]);
    57     //不放入当前物品 
    58     f(i+1,weight,val);
    59 }  
    60 float f1(int i,int weight){//剩余最大价值。 
    61     float sum = 0;
    62     while(weight>=w[i]&&i<n){
    63         sum += v[i];
    64         weight -= w[i];
    65         i++;
    66     }
    67     if(i<n&&weight>0){
    68         sum += weight*U[i];        
    69     }
    70     return sum;
    71 } 

    运行结果:

    不剪枝递归次数:

    不考第一个约束条件递归次数:

    不考虑第二个约束条件:

    考虑所有约束条件先放进去:

    考虑所有约束条件先不放进去:

    可以看出剪枝越多效率越高。且同样约束条件下先放与不先放递归次数不同。一般先放递归次数少效率高。

  • 相关阅读:
    未能正确加载“Microsoft.VisualStudio.Editor.Implementation.EditorPackage”包
    Only one instance of a ScriptManager can be added to the page.
    springboot SSM
    spring mvc 请求转发和重定向
    Spring Boot 配置 Swagger2 接口文档引擎
    solr
    jQuery
    反向代理负载均衡-Nginx
    mybatis二级缓存
    Vue的路由
  • 原文地址:https://www.cnblogs.com/lolybj/p/9905373.html
Copyright © 2011-2022 走看看