一、问题描述

有一天,阿里巴巴赶着一头毛驴上山砍柴。砍好柴准备下山时,远处突然出现一股烟尘,弥漫着直向上空非扬,朝他这儿卷过来,而且越来越近。靠近以后,他才看清原来是一支马队,他们公有四十人,一个个年轻力壮、行动敏捷。一个首领模样的人背负沉重的鞍袋,从丛林中一支来打那个大石头跟前,喃喃地说到:“芝麻、开门吧!”,随着那个头目的喊声,大石头前突然出现一道宽阔的门路,于是强盗们鱼贯而入。阿里巴巴待在树上观察他们,直到他们走的无影无踪之后,才从树上下来。他大声喊道:“芝麻、开门吧!”,他的喊声刚落,洞门立刻打开了,他小心翼翼地走了进去,一下子惊呆了,洞中堆满了财务,还有多的无法计数的金银财宝,有的散堆在地上,有的盛在皮袋中。突然看见这么多的金银财宝,阿里巴巴深信这肯定是一个强盗们数代经营、掠夺所积累起来的宝窟。为了让乡亲们开开眼界,见识一下这些宝物,他想一种宝物只拿一个,如果太重就用锤子凿开,但毛驴的运载能力是有限的,怎么才能用驴子运走最大价值的财宝分给穷人呢?


二、问题分析

假设山洞中有n种宝物,每种宝物有一定重量w和相应的价值v,毛驴运载能力有限,只能运走m重量的宝物,一种宝物只能拿一样,宝物可以分割。那么怎么才能使毛驴运走宝物的价值最大呢?
(1)每次挑选价值最大的宝物装入背包,得到的结果是否最优?
(2)每次挑选重量最小的宝物装入背包,能否得到最优解?
(3)每次选择单位重量价值最大的宝物,能否使价值最高?

如果选择价值最大的宝物,但重量非常大,也是不行的,因为运载能力是有限的,所以舍弃策略(1);如果选重量小的物品装入,那么其价值不一定高,所以不能再总重限制的情况下保证价值最大,所以舍弃策略(2);而第三种是每次选择单位重量价值最大的宝物,也就是说每次选择性价比(价值/重量)最高的宝物,如果可以达到运载重量m,那么一定能使得价值最大,因此采用策略(3),每次从剩下的宝物中选择性价比最高的宝物。


三、算法设计

3.1、数据结构及其初始化

n种宝物的重量和价值存储结构体three(包含重量、价值、性价比3个成员)中,同时求出每种宝物的性价比也存储在对应的结构体three中,将其按照性价比从高到低排序。采用sum来存储毛驴能够运走的最大价值,初始化为0;

3.2、贪心策略

按照性价比从大到小选取宝物,直到达到毛驴的运载能力。每次选择性价比高的物品,判断是否小于m(毛驴运载能力),如果小于m,则放入,sum(已放入物品的价值)加上当前宝物的价值,m减去放入宝物的重量;如果不小于m,则取该宝物的一部分m*p[i]m=0时,程序结束。m减少到0,则sum得到最大值。

按照贪心策略,每次选择性价比高的宝物放入:

  • 第1次选择宝物2,剩余容量30-2=28,目前装入最大价值为8;
  • 第2次选择宝物10,剩余容量28-5=23,目前装入最大价值为8+15=23;
  • 第3次选择宝物6,剩余容量23-8=15,目前装入最大价值为23+20=43;
  • 第4次选择宝物3,剩余容量15-9=6,目前装入最大价值为43+18=61;
  • 第5次选择宝物5,剩余容量6-5=1,目前装入最大价值为61+8=69;
  • 第6次选择宝物8,剩余容量1<4,装入1,目前装入最大价值为69+(6/4)*1=70.5;

3.3、构造最优解

把这些让如的宝物序号组合在一起,就得到了最优解(2,10,6,3,5,8),其中最后一个宝物为部分装入(装入1单位),能够装入宝物的最大价值为70.5


四、代码设计

4.1、数据结构定义

根据算法设计中的数据结构,首先定义一个结构体three

struct three {double w;  //每种宝物的重量double v;  //每种宝物的价值double p;  //每种宝物的性价比(价值/重量)
}

4.2、性价比排序

可以利用C++中的排序函数sort,对宝物的性价比进行从小到大(非递减)排序。要使用此函数需引入头文件:

#include <algorithm>sort(begin, end)  //参数begin和end表示一个范围,分别为待排序数组的首地址和尾地址
//sort 函数默认为升序

在本例中采用结构体形式存储,按结构体中的一个字段,即性价比排序。如果不适用自定义比较函数,那么sort函数排序时不知道按哪一项的值排序,因此采用自定义比较函数的办法实现宝物性价比的降序排序:

bool cmp(three a,three b)  //比较函数按照宝物性价比降序排序
{return a.p > b.p;  //指明按照宝物性价比降序排序
}
//前两个参数分别为待排序数组的的首地址和尾地址
//最后一个参数compare表示比较的类型
sort(s,s+n,cmp);

4.3、贪心算法求解

在性价比排序的基础上,进行贪心算法运算。如果剩余容量比当前宝物的重量大,则可以放入,剩余容量减去当前宝物的重量,已房屋物品的价值加上当前宝物的价值。如果剩余容量比当前宝物的重量小,表示不可以全部放入,可以切割下来一部分(正好是剩余容量),然后令剩余容量乘以当前物品的单位重量价值,已放入物品的价值加上该价值,即为能放入宝物的最大价值。

for(int i=0; i<n; i++)  //按照排好的顺序,执行贪心策略
{if( m > s[i].w)  //如果宝物的重量小于毛驴的运载能力,即剩余容量{m -= s[i].w;sum += s[i].v;}else  //如果宝物的总量大于毛驴的承载能力{//进行宝物切割,切割一部分(m重量),正好达到毛驴称重sum += m * s[i].p;  break;}
}

五、代码设计

#include <iostream>
#include <algorithm>using namespace std;const int M=1000005;struct three {double w;  //每个宝物的重量double v;  //每个宝物的价值double p;  //每个宝物的性价比
}s[M];bool cmp(three a, three b)
{return a.p > b.p;  //根据宝物的单位价值从大到小排序
}int main()
{int n;  //n 表示有n个宝物double m;  //m 表示毛驴的承载能力cout<<"请输入宝物数量n及毛驴的承载能力m:"<<endl;cin>>n>>m;cout<<"请输入每个宝物的重量个价值,用空格分开:"<<endl;for(int i=0; i<n; i++){cin>>s[i].w>>s[i].v;s[i].p=s[i].v/s[i].w;  //每个宝物单位价值}sort(s,s+n,cmp);double sum = 0.0;  //sum 表示贪心记录运走宝物的价值之和for(int i=0; i<n; i++)  //按照排好的顺序,执行贪心策略{if( m > s[i].w)  //如果宝物的重量小于毛驴的运载能力,即剩余容量{m -= s[i].w;sum += s[i].v;}else  //如果宝物的总量大于毛驴的承载能力{//进行宝物切割,切割一部分(m重量),正好达到毛驴称重sum += m * s[i].p;  break;}}cout<<"装入宝物的最大价值Maximun value= "<<sum<<endl;return 0;
}

六、算法复杂度分析

6.1、时间复杂度

该算法的时间主要耗费在将宝物按照性价比排序上,采用的是快速排序,算法时间复杂度为O(nlogn)

6.2、空间复杂度

空间主要耗费在存储宝物的性价比,空间复杂度为O(n)

6.3、总结

为了使m重量里的所有物品的价值最大,利用贪心思想,每次取剩下物品里面性价比最高的物品,这样可以使得在相同重量条件下比选其他物品所得到的价值更大,因此采用贪心策略能得到最优解。(物品可分割的装载问题称为背包问题,物品不可分割的装载问题称为0-1背包问题)。

贪心算法--阿里巴巴与四十大盗--背包问题相关推荐

  1. 【贪心】阿里巴巴与四十大盗-背包问题

    题目 阿里巴巴因为偶然的机会进入了强盗们的宝库,他想拿走一些让乡亲们开开眼.他想每种宝物只拿一个,如果太重就用锤子凿开,但毛驴运载能力有限,怎么才能用毛驴运走最大价值的宝物呢? 数据 输入 第一行:宝 ...

  2. 2.3阿里巴巴与四十大盗——背包问题

    2.3阿里巴巴与四十大盗--背包问题 2.3.1问题分析 2.3.2算法设计 2.3.3 完美图解 2.3.4 伪代码详解 2.3.5 实战演练 2.3.6算法分析及优化拓展 1.算法复杂度分析 2. ...

  3. 贪心算法之阿里巴巴与四十大盗——背包问题

    14天阅读挑战赛 有一天,阿里巴巴赶着一头毛驴上山砍柴.砍好柴准备下山时,远处突然出现一股烟尘,弥漫着向上空飞扬,朝他这儿卷过来,而且越来越近.阿里巴巴心里害怕,担心碰到的是一伙儿强盗,他赶紧把毛驴赶 ...

  4. 【贪心算法】阿里巴巴与四十大盗——背包问题与0-1背包问题

    前言 关于贪心算法,我在这篇博客中已经做了简单的介绍.初识贪心算法 下面来介绍一下贪心算法中的一个经典的问题--背包问题 一.问题描述 一天,阿里巴巴赶着一头毛驴上山砍柴,无意间在远处发现了一群盗贼, ...

  5. 2.3阿里巴巴与四十大盗 背包问题

    有一天,阿里巴巴赶着一头毛驴上山砍柴.砍好柴准备下山时,远处突然出现一股烟尘,弥漫着直向上空飞扬,朝他这儿卷过来,而且越来越近.靠近以后,他才看清原来是一支马队,他们共有四十人,一个个年轻力壮.行动敏 ...

  6. 阿里巴巴与四十大盗——背包问题

    C++源码: #include<iostream> #include<algorithm> #include<conio.h> const int M=100000 ...

  7. 贪心算法之阿里巴巴与四十大盗(背包问题)

    1.问题 有一天,阿里巴巴赶着一头毛驴上山砍柴.砍好柴准备下山时,远处突然出现一股烟尘,弥漫着直向上空飞扬,朝他这儿卷过来,而且越来越近.靠近以后,他才看清原来是一支马队,他们共有四十人,一个个年轻力 ...

  8. 贪心算法 | 背包问题——阿里巴巴与四十大盗

    2.背包问题--阿里巴巴与四十大盗 问题:有一天,阿里巴巴赶着一头毛驴上山砍柴.砍好柴准备下山时,远处突然出现一股烟尘,弥漫着直向上空非扬,朝他这儿卷过来,而且越来越近.靠近以后,他才看清原来是一支马 ...

  9. 贪心——阿里巴巴与四十大盗(可拆分背包)

    问题 F: 阿里巴巴与四十大盗 时间限制: 1 Sec  内存限制: 128 MB 提交: 215  解决: 123 [提交][状态][讨论版][命题人:quanxing] 题目描述 有一天,阿里巴巴 ...

最新文章

  1. Thecus色卡司1U机架式网络存储服务器
  2. java usbkey数字证书_Java创建数字证书
  3. 简单的css缩放动画,仿腾讯新闻的分享按钮和美团app底部的图标样式
  4. HTML+CSS+JS实现 ❤️制作loading动画效果❤️
  5. 计算仰角_41页最新全站仪测量方法及计算+图文解说,助你轻松掌握测量
  6. WampServer下使用PHP
  7. Chrome浏览器扩展开发系列之十五:跨域访问的XMLHttpRequest对象
  8. 阶段3 3.SpringMVC·_05.文件上传_1 文件上传之上传原理分析和搭建环境
  9. 代码管理学:常量类应该单独一个目录,还是在模块目录下?
  10. YDOOK:STM32: 最新版选型手册下载 2021
  11. 逸致金品:如何从零开始学习板绘?
  12. JS 动态添加的元素 绑定事件
  13. Fishermen(2018 ICPC SouthEastern European)
  14. UE5 Metahuman使用Live Link Face动画不匹配的问题修复
  15. 初识机器学习前导内容_你需要知道的基本概念罗列_以PY为工具 【Python机器学习系列(一)】
  16. IoT僵尸网络Miori通过ThinkPHP远程代码执行漏洞进行传播
  17. A2Billing 代码分析
  18. html 边框素材,2000+ 精美蕾丝、花边、边框素材
  19. Vue.js实战梁笔记02(第3-5章)
  20. 単語ーー下げる(さげる)

热门文章

  1. networkx 给图的所有边添加相同的属性
  2. 学术报告系列(五) - 基于智能机器人的室内空间巡检巡查方案
  3. 无线投屏服务器连接不上去,极速投屏连接成功了为什么投不上去
  4. 如何将 iOS 15 Beta 降级到 iOS 14.x
  5. 常见的NoSQL数据库四大分类
  6. c语言 机械 考研真题,2016年东北理工大学机械与电子工程学院C语言程序设计(同等学力加试)考研复试题库...
  7. psycopg2使用大全
  8. MIKE水动力笔记9_大潮小潮对应的涨急落急时刻流场图
  9. OAuth2简介生成accessToken(一)
  10. Google字体库引起的首页加载缓慢的解决方法