贪心练习:阿里巴巴与十四大盗————背包问题


 转自:https://blog.csdn.net/qq_34624515/article/details/84583149

问题描述

  假设山洞里有 n 种宝物,每种宝物有一定重量 w 和相应的价值 v ,毛驴运载能力有限,只能运走 m 重量的宝物,

  一种宝物只能拿一样,宝物可分割。那么如何使毛驴运  走最大价值的宝物?

问题分析:

  物品可分割的装载问题为背包问题,物品不可以分割的装载问题为0-1背包问题

【思考过程】

  如果选价值量最大的宝物,那重量不一定小,不行;

  如果选重量最小的宝物,那价值不一定高,也不行;

  每次选取单位重量价值最大的宝物,即每次选择性价比(价值/重量)最高的宝物,达到运载重量 m ,那一定是价值最大的。

【算法设计】

 (1)数据结构及初始化。将 n 种宝物的重量和价值存储在结构体 three(含重量、价值、性价比),按性价比从高到底排序。

   用 sum 来存储毛驴能够运走的最大价值,初始量为 0。

 (2)根据贪心策略,按性价比从大到小选宝物,直到达到毛驴的运载能力。每次选性价比高的物品,判断是否小于 m ,若小于则放入,

   sum加上当前宝物的价值,m减去当前宝物的重量;若大于,则取该宝物的一部分 m*p[i] , m=0 ,程序结束。m减少到0,则sum得到最大值。

 1  #include <bits/stdc++.h>
 2  using namespace std;
 3  const int MAXN=10000;
 4  double sum=0.0;                    //记录贪心选择宝物的价值之和 
 5  struct three{
 6      double w;                        //每个宝物的重量
 7     double v;                        //每个宝物的价值
 8     double p;                        //性价比=价值/重量 
 9  }s[MAXN];
10  bool cmp(three a,three b){            //定义sort的比较类型,按照宝物性价比降序 
11      return a.p>a.p;                    //按照性价比降序排列sort(s,s+n,cmp) 
12  }
13  int main(){
14      int n;                            //宝物的数量
15     double m;                        //能运走 m 重量的宝物
16     cin>>n>>m;
17     for(int i=0;i<n;i++){
18         cin>>s[i].w>>s[i].v;        //读入宝物重量和价值 
19         s[i].p=s[i].v/s[i].w;         
20     } 
21     sort(s,s+n,cmp);
22     for(int i=0;i<n;i++){ 
23         if(m>s[i].w){                //宝物重量小于承载能力则可以选择
24             m-=s[i].w;
25             sum+=s[i].v; 
26         }else{
27             sum+=m*s[i].p;            //不足装入整个宝物,部分装入 
28             break; 
29         }                        
30     } 
31     cout<<sum<<endl;
32     return 0;
33  } 

 有问题的代码


 经学长改进后:

 1 //  main.cpp
 2 //  demo
 3 //
 4 //  Created by MYL on 2020/2/29.
 5 //  Copyright  2020 马英粼. All rights reserved.
 6 //
 7 #include <iostream>
 8 #include <algorithm>
 9 #include <cstring>
10 #include <vector>
11 using namespace std;
12 const int maxn = 1e5+10;
13 struct good{
14     double w, v, xingjiabi; //重量和价值
15 } goods[maxn];
16 int n,  weight;
17 double ans;
18 bool cmp (good a, good b) {
19     return a.xingjiabi > b.xingjiabi;
20 }
21 int main(int argc, const char * argv[]) {
22     cin >> n >> weight;
23     for (int i = 1; i <= n; i++) {
24         cin >> goods[i].w >> goods[i].v;
25         goods[i].xingjiabi = goods[i].v / goods[i].w;
26     }
27     sort(goods+1, goods+1+n, cmp);
28     int cnt = 1;
29     while (weight) {
30         if (goods[cnt].w <= weight) {
31             ans += goods[cnt].v;
32             weight -= goods[cnt].w;
33             cnt++;
34             continue;
35         } else {
36             ans += weight * goods[cnt].xingjiabi;
37             weight = 0;
38         }
39     }
40     cout << ans;
41     return 0;
42 }

感谢大佬QAQ

另外推荐背包九讲:https://www.cnblogs.com/StungYep/p/12254086.html

posted on 2020-02-28 17:39  恒晨  阅读(310)  评论(0编辑  收藏  举报

导航