• 01背包问题回溯法和动态规划


    题目要求:

    输入背包的容量v和物品的数量n;接下来n 行每行输入两个数字,第一个是物品质量,第二个是物品价值;

    输出背包容纳物品的最大价值。

    下面直接贴代码:

    回溯法

     1 #include<iostream>//之前必须知道背包容量和n个物品 
     2 #include<algorithm>
     3 using namespace std;
     4 class Property
     5 {
     6     public: 
     7     int weight,profit;
     8     double average;
     9     friend bool operator<(Property a,Property b)
    10     {
    11         return a.average>b.average;
    12     }
    13 };
    14 class Pack
    15 {
    16     public:
    17         Pack(int Q,int n)//构造函数,初始化 
    18         {
    19             capcity=Q;
    20             number=n;
    21             property=new Property[n+1];
    22             bestp=cw=cp=0;
    23         }
    24         ~Pack()
    25         {
    26             delete []property;
    27         }
    28         void inputproperty()
    29         {
    30             for(int i=0;i<number;i++)
    31             {
    32                 cin>>property[i].weight>>property[i].profit;
    33                 property[i].average=1.0*property[i].profit/property[i].weight;
    34             }
    35             sort(property,property+number);
    36         }
    37         int command()
    38         {
    39             int totalweight=0;
    40             int totalvalue=0;
    41             for(int i=0;i<number;i++)
    42             {
    43             totalweight+=property[i].weight;
    44             totalvalue+=property[i].profit;
    45             }
    46             if(totalweight<capcity)return totalvalue;
    47             backtrack(0);
    48             return bestp;
    49         }
    50         bool bound(int i)
    51         {
    52             int currentp=cp;
    53             int currentw=capcity-cw;
    54             while(currentw>=property[i].weight&&i<number)
    55             {
    56                 currentw-=property[i].weight;
    57                 currentp+=property[i].profit;
    58                 i++;
    59             }
    60             if(i<number)
    61             currentp+=1.0*property[i].profit*currentw/property[i].weight;
    62             return currentp>bestp;
    63         }
    64         void backtrack(int i)
    65         {
    66             if(i>number-1)
    67             {
    68                 if(bestp<cp)
    69                 bestp=cp;
    70                 return;
    71             }
    72             if(cw+property[i].weight<=capcity)//此处必须用<=比较符号,不然会错 
    73             {
    74                 cw+=property[i].weight;
    75                 cp+=property[i].profit;
    76                 backtrack(i+1);
    77                 cw-=property[i].weight;
    78                 cp-=property[i].profit;
    79             }
    80             if(bound(i+1));
    81             backtrack(i+1);
    82         }
    83     private:
    84     int capcity,number;    
    85     Property *property;
    86     int cw,cp,bestp; 
    87 };
    88 int main()
    89 {
    90     int n,m;
    91     while(cin>>n>>m)
    92     {
    93         Pack object(n,m);
    94         object.inputproperty();
    95         cout<<object.command()<<endl;
    96     }
    97     return 0;
    98 }

    输入:

    20 5
    4 7
    5 8
    2 10
    5 10
    8 16

    输出:
    44

    动态规划法

     1 #include<iostream>
     2 #include<cstring>
     3 using namespace std;
     4 int main()
     5 {
     6     int Capcity,weight;
     7     int *w,*p;
     8     int profit[200][200];
     9     while(cin>>Capcity>>weight)
    10     {
    11         memset(profit,0,sizeof(profit));
    12         w=new int[weight+1];
    13         p=new int[weight+1];
    14         for(int i=1;i<=weight;i++)
    15         cin>>w[i]>>p[i];//输入重量和价值 
    16         for(int i=1;i<=weight;i++)
    17         {
    18             for(int j=1;j<=Capcity;j++)
    19             {
    20                 if(w[i]>j)profit[i][j]=profit[i-1][j];
    21                 else if(profit[i-1][j]<profit[i-1][j-w[i]]+p[i])
    22                 profit[i][j]=profit[i-1][j-w[i]]+p[i];
    23                 else profit[i][j]=profit[i-1][j];
    24             }
    25         }
    26         for(int i=1;i<=weight;i++)
    27         {
    28         for(int j=1;j<=Capcity;j++)
    29         {
    30             cout<<profit[i][j]<<" ";
    31         }
    32         cout<<endl;    
    33         }
    34     }
    35     return 0;
    36 }
    What I don't dare to say is I can't!
  • 相关阅读:
    联想Thinkpad L460安装Win7 64位
    2019牛客暑期多校训练营(第六场)E 构造、原图是补图的同构图
    网络流24题 P2766 最长不下降子序列问题
    The 2019 ICPC China Nanchang National Invitational and International Silk-Road Programming Contest B、H
    P4781 拉格朗日插值
    P4717 快速沃尔什变换FWT 模板题
    2019CCPC-江西省赛C题 HDU6569 GCD预处理+二分
    Gym 101917 E 简单计算几何,I 最大流
    51 Nod 1238 最小公倍数之和 V3 杜教筛
    51Nod 1237 最大公约数之和 V3 杜教筛
  • 原文地址:https://www.cnblogs.com/sytu/p/3861587.html
Copyright © 2020-2023  润新知