经典案例解析贪心算法

贪心算法,又名贪婪算法,顾名思义,是指在对问题求解时,总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。

贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。如单源最短路经问题,最小生成树问题,背包最大价值问题等。在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似。

这里我们采用更容易理解的背包最大价值问题:

有一个背包,最多能承载重量为C=150的物品,现在有7个物品(物品不能分割成任意大小),编号为1~7,重量分别是wi=[35,30,60,50,40,10,25],价值分别是pi=[10,40,30,50,35,40,30],现在从这7个物品中选择一个或多个装入背包,要求在物品总重量不超过C的前提下,所装入的物品总价值最高。这里需要明确的几个点:1.每个物品都有重量和价值两个属性;2.每个物品分被选中和不被选中两个状态(后面还有个问题,待讨论);3.可选物品列表已知,背包总的承重量一定。所以,构建描述每个物品的数据体结构OBJECT和背包问题定义为://typedef是类型定义的意思

//定义待选物体的结构体类型typedefstructtagObject{intweight;intprice;intstatus;}OBJECT;//定义背包问题typedefstructtagKnapsackProblem{vectorobjs;inttotalC;}KNAPSACK_PROBLEM;如下,实例化objectsOBJECTobjects[]={{35,10,0},{30,40,0},{60,30,0},{50,50,0},

{40,35,0},{10,40,0},{25,30,0}};

那么,我们思考一下,如何选,才使得装进背包的价值最大呢?

策略1:价值主导选择,每次都选价值最高的物品放进背包;

策略2:重量主导选择,每次都选择重量最轻的物品放进背包;

策略3:价值密度主导选择,每次选择都选价值/重量最高的物品放进背包。

策略1:价值主导选择

每次都选价值最高的物品放进背包根据这个策略最终选择装入背包的物品编号依次是4、2、6、5,此时包中物品总重量是130,总价值是165。//遍历没有被选的objs,并且选择price最大的物品,返回被选物品的编号

intChoosefunc1(std::vector&objs,intc){intindex=-1;//-1表示背包容量已满intmax_price=0;//在objs[i].status==0的物品里,遍历挑选objs[i].price最大的物品for(inti=0;i(objs.size());i++){if((objs[i].status==0)&&(objs[i].price>max_price))//objs没有被选,并且price>max_price{max_price=objs[i].price;index=i;}}returnindex;}策略2:重量主导选择

每次都选择重量最轻(小)的物品放进背包根据这个策略最终选择装入背包的物品编号依次是6、7、2、1、5,此时包中物品总重量是140,总价值是155。intChoosefunc2(std::vector&objs,intc)

{intindex=-1;intmin_weight=10000;for(inti=0;i(objs.size());i++){if((objs[i].status==0)&&(objs[i].weight

每次选择都选价值/重量最高(大)的物品放进背包物品的价值密度si定义为pi/wi,这7件物品的价值密度分别为si=[0.286,1.333,0.5,1.0,0.875,4.0,1.2]。根据这个策略最终选择装入背包的物品编号依次是6、2、7、4、1,此时包中物品的总重量是150,总价值是170。intChoosefunc3(std::vector&objs,intc)

{intindex=-1;doublemax_s=0.0;for(inti=0;i(objs.size());i++){if(objs[i].status==0){doublesi=objs[i].price;si=si/objs[i].weight;if(si>max_s){max_s=si;index=i;}}}returnindex;}回过头来,我们再来根据贪心算法的定义来对这个问题进行贪心算法GreedyAlgo:

voidGreedyAlgo(KNAPSACK_PROBLEM*problem,SELECT_POLICYspFunc){intidx;intsum_weight_current=0;//先选while((idx=spFunc(problem->objs,problem->totalC-sum_weight_current))!=-1){//再检查,是否能装进去if((sum_weight_current+problem->objs[idx].weight)<=problem->totalC){problem->objs[idx].status=1;//如果背包没有装满,还可以再装,标记下装进去的物品状态为1sum_weight_current+=problem->objs[idx].weight;//把这个idx的物体的重量装进去,计算当前的重量}else{//不能选这个物品了,做个标记2后重新选剩下的problem->objs[idx].status=2;}}PrintResult(problem->objs);//输出函数的定义,查看源代码}主函数部分OBJECTobjects[]={{35,10,0},{30,40,0},{60,30,0},{50,50,0},

{40,35,0},{10,40,0},{25,30,0}};intmain(){KNAPSACK_PROBLEMproblem;problem.objs.assign(objects,objects+7);//assign赋值,std::vector::assignproblem.totalC=150;cout<<"Starttofindthebestway,NOW"<

THE END
1.刷题29天贪心算法那么又要贪心了,局部最优:取candyVec[i + 1] + 1 和 candyVec[i] 最大的糖果数量,保证第i个小孩的糖果数量既大于左边的也大于右边的。全局最优:相邻的孩子中,评分高的孩子获得更多的糖果。 c++ classSolution{public:intcandy(vector<int>&ratings){vector<int>candyVec(ratings.size(),1);//1从前往后https://zhuanlan.zhihu.com/p/11941030486
2.算法第二十五天贪心贪心算法的核心思想就是,局部最优推出全局最优。 优先大饼干满足大胃口,或者小饼干满足小胃口,都可以完成目标。 376. 摆动序列 classSolution{publicintwiggleMaxLength(int[]nums){if(nums.length<=1){return1;}intpreDiff=0;intcurDiff=0;intresult=1;// 因为默认最后面是一个峰值for(inti=0;i<nums.lengthhttps://www.jianshu.com/p/89ecffe0a5ec
3.今日热搜丨贪心算法贪心的意思 在于在作出选择时,每次都要选择对自身 最为有利的结果,保证自身利益的最大化。贪心算法就是利用 这种贪心思想而得出一种算法。关于贪心算法,一起来了解!什么是贪心算法 贪心算法(greedy algorithm ,又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,该算法在每个https://baijiahao.baidu.com/s?id=1742021741621560533&wfr=spider&for=pc
4.《趣学算法》第二章贪心算法源代码zengpingfun贪心算法相关代码实现 1、加勒比海盗船——最优装载问题 2、阿里巴巴与四十大盗——背包问题 3、高级钟点秘书——会议安排 4、一场说走就走的旅行——最短路径 5、神秘电报密码——哈夫曼编码 6、沟通无限校园网——最小生成树 贪心算法相关代码实现 https://www.cnblogs.com/self-confidence/p/13603491.html
5.js贪心算法钱币找零问题代码实例javascript技巧这篇文章主要介绍了js贪心算法 钱币找零问题代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下GPT4.0+Midjourney绘画+国内大模型 会员永久免费使用!【 如果你想靠AI翻身,你先需要一个靠谱的工具!】给定一组硬币的面额,以及要找零的钱数,计算出符合找零钱数https://www.jb51.net/article/169824.htm
6.免费贪心算法详解与实际使用示例代码贪心算法资源算法设计方法:系统性地介绍了贪心算法的设计原则、证明技巧和实现注意事项,帮助读者更好地理解和应用贪心策略。扩展内容:涵盖了贪心算法与动态规划、分治等其他算法的结合应用,以及随机化贪心、并行贪心等进阶主题。 这份教程采用循序渐进的方式,从理论到实践,从基础到进阶,配合丰富的代码示例和详细的解释,适合想要深入https://download.csdn.net/download/weixin_55344375/89997619
7.贪恋算法(贪心算法)的一些例题及部分matlab代码贪恋算法(贪心算法)的一些例题及部分matlab代码-经管之家官网! 贪恋算法(贪心算法)的一些例题及部分matlab代码 人大经济论坛-经管之家:分享大学、考研、论文、会计、留学、数据、经济学、金融学、管理学、统计学、博弈论、统计年鉴、行业分析包括等相关资源。https://bbs.pinggu.org/jg/qikan_qikanku_8585085_1.html
8.代码随想录投稿视频代码随想录视频分享贪心算法的巧妙需要慢慢体会!LeetCode:53. 最大子序和 4.9万2023-1-16 22:57 6.2万2023-1-13 12:39 8万2023-1-11 4.4万2023-1-9 16:49 19:18 4.8万2023-1-6 17:15 16:28 登录后你可以: 免费看高清视频 多端同步播放记录 发表弹幕/评论 https://space.bilibili.com/525438321/video
9.贪心算法WOODENSTICKS实例代码贪心算法 WOODEN STICKS 实例代码 Problem Description There is a pile of n wooden sticks. The length and weight of each stick are known in advance. The sticks are to be processed by a woodworking machine in one by one fashion. It needs some time, called setup time, for the machine to https://www.xiuzhanwang.com/a1/Cyuyan/4505.html
10.java贪心算法换硬币mob64ca12eaf194的技术博客换硬币问题是经典的动态规划题目,也是贪心算法的一个重要应用。简单来说,换硬币问题是指在给定的面额和数量的情况下,如何用最少的硬币数量来凑成一个特定的金额。本文将深入探讨这一问题,并通过 Java 代码示例帮助读者理解贪心算法在这一问题中的应用。 https://blog.51cto.com/u_16213409/12864082
11.2020届计算机科学方向毕业设计(论文)阶段性汇报代码算法自动分类的研究 课题进展总体较顺利。于收集数据方面,在APEX实验室的帮助下,获得了7千余例HDU和POJ上的源代码及其对应的标签,大大加快了课题的进展。于设计算法方面,基于目前现有的研究都依靠语法树、控制流图和数据流图进行分析的现状,初步设计了从源代码直接入手进行分类的软件。目前的F1分数约在70左右,正https://zhiyuan.sjtu.edu.cn/html/zhiyuan/announcement_view.php?id=3709
12.C++算法集锦(14):贪心算法腾讯云开发者社区代码实现 跳跃游戏 II 思路 贪心算法 贪心算法可以理解为一种特殊的动态规划为题,拥有一些更加特殊的性质,可以进一步降低动态规划算法的时间复杂度。 来看几道题目熟悉一下这种“不断寻求局部最优”的算法。 跳跃游戏 I 输入一个非负整数数组nums,数组元素nums[i]表示的是:如果你站在位置 i ,最多能够往前跳几步https://cloud.tencent.com/developer/article/1879118
13.贪心算法WOODENSTICKS实例代码贪心算法 WOODEN STICKS 实例代码,需要的朋友可以参考一下 贪心算法 WOODEN STICKS2020-09-05 上传大小:37KB 所需:18积分/C币 用贪心算法解单源最短路径问题 用贪心算法解单源最短路径问题 明确单源最短路径问题的概念;利用贪心算法解决单源最短路径问题;并通过本例熟悉贪心算法在程序设计中的应用方法。 https://www.iteye.com/resource/weixin_38720756-12814957