关于对贪心算法的理解
创始人
2024-06-03 17:23:51
0

一.概念理解

1.何为贪心算法?

贪心算法(greedy algorithm [8] ,又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解 。

2.贪心算法的特征

  • 1、有一个以最优方式来解决的问题。为了构造问题的解决方案,有一个候选的对象的集合:比如不同面值的硬币 。

  • 2、随着算法的进行,将积累起其他两个集合:一个包含已经被考虑过并被选出的候选对象,另一个包含已经被考虑过但被丢弃的候选对象 。

  • 3、有一个函数来检查一个候选对象的集合是否提供了问题的解答。该函数不考虑此时的解决方法是否最优 [3] 。

  • 4、还有一个函数检查是否一个候选对象的集合是可行的,即是否可能往该集合上添加更多的候选对象以获得一个解。和上一个函数一样,此时不考虑解决方法的最优性 。

  • 5、选择函数可以指出哪一个剩余的候选对象最有希望构成问题的解 。

  • 6、最后,目标函数给出解的值


二.思路解析及结合具体题目进行贪心策略的选择sad

1.思路总述:

贪心算法是所有算法中最灵动的算法,对于贪心题目而言,我们解决问题的关键在于能够找到其正确的贪策略,但是说句实在话,对于不同的题目和应用场景,几乎每道题目都有属于自己的解题思路,我们能做的在很大程度上只能说是总结;与此同时,贪心算法同样也是最符合自然智慧的算法,贪心算法的起源来自于生活场景,因此,根据不同生活场景进行部署不同的贪心策略,同样有助于我们解决问题。

接下来,我们根据不同的题目进行不同贪心策略的部署:

1.会议问题

大家都知道,老板总是很忙,每天有很多会等着老板参加,但老板又没有时间参加所有的会议,所以需要秘书来合理安排。
某一天,老板对秘书说:“你安排一下,我希望今天尽可能多参加几场会议”。秘书看了一下如下希望老板参加的会议,她应该如何安排,才能使老板参加会议的场次最多? [[8,10],[9,11],[10,15],[11,14],[13,16],[14,17],[15,17],[17,18],[18,20],[16,19]] 列表里的每一个子列表都表示一场会议比如第一场会议[8,10],表示这场会议开始时间是8点,结束时间是10点。

我们试着分析一一下这个问题:如果想要合理安排会议以至于在一天中安排的会议场数最多,我们必须要找到一个标准来决定会议安排的时间先后问题,而这便是这个问题的贪心策略的着手点,那标准是会议开始的越早就先安排这场会议吗?(反例:如果一场会议从早上开到晚上结束呢?,这样只能安排一场会议了)这个策略显然不合理,与此相反,恰好是哪场会议结束的最早,我们先安排哪场会议(因为一天的时间是一定的,如果先安排早结束的会议,意味着我们有更多的时间去安排后面的会议,而这便是这个题目贪心策略的关键点)

基于这个思路,我们进行code:

public class ConferenceForGreedy {public static void main(String[] args) {}public int conferenceGreedy(Conference[]programs){if(programs==null||programs.length==0){return  0;}int result=0;int timeLine=0;//对数组进行排序Arrays.sort(programs,new sorts());//对数组进行遍历放入for (int i = 0; i < programs.length; i++) {if(programs[i].start>=timeLine){//符合条件就对会议的数量进行增加result++;//不断去更迭timeLinetimeLine=programs[i].end;}}return result;}
//重写比较器,使结束时间早的会议排在数组的前面public static class sorts implements Comparator {@Overridepublic int compare(Conference o1, Conference o2) {return o1.end-o2.end;}}
}
2.股票抛售问题
给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。
在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。返回 你能获得的 最大 利润 。

我们通过上面的实例能够发现:我们能够预知未来(知道未来几天股票价格的跌落),如果在这样的情况下,那我们的贪心策略就很容易进行抉择了:第一天买入股票,如果预知到后面某一天股票价格跌落,就在前一天将股票进行抛售;如果后面的日子股票价格没有跌落,那我们就继续等待(赚更多的钱)

我们在这种思路下来code:

class Solution {public int maxProfit(int[] prices) {//思路:在当前情况下做出做优决定:如果股票在明天降价或者不变,我们就在今天卖出,如果价格上升,保留//检查数组的有效性if(prices.length==1){return 0;}int profits=0;//-1状态表示当前手中没有股票int tacket=-1;for(int i=0;iprices[i]){//继续等待continue;}else{//进行抛售profits+=prices[i]-tacket;tacket=-1;}}//检查最后一天,不是0说明最后一天股票价格上涨if(tacket!=-1){profits+=prices[prices.length-1]-tacket;}return profits;}
}
3.路灯问题
给定一个字符串str,只由‘X’和‘.’两中国字符构成。
‘X’表示墙,不能放灯,也不需要点亮,‘.’表示居民点,可以放灯,需要点亮。
如果灯放在i位置,可以让i-1,i和i+1三个位置被点亮,返回如果点亮str中所需要点亮的位置,至少需要几盏灯
例如: X…X…X…X. 需要至少5盏灯
思路概述:这道题的关键点用一句话可以概括为用最少的灯点亮全部的居民点,我们按照不同的情况进行不同的策略部署:

在思路的指引下:我们直接进入code:

package greedy;/*** @author tongchen* @create 2023-03-09 9:31*/
public class LightForGreedy {public static void main(String[] args) {}public int PlacesForGreedy(char[]chars){int index=0;//遍历变量int lights=0;while(index

通过这三个题目,我们能够总结一点:不同的贪心题目具有不同的应用场景,贪心策略也随之有所变化,

除了找到正确的贪心策略之外,我们仍然可以采用“试”的方法求得最优解:

我们拿会议问题和路灯问题来给出代码实例:

  1. 会议问题

package greedy;/*** @author tongchen* @create 2023-03-09 8:09*/
public class ConferenceForViolence {public static void main(String[] args) {}//创建不断递归的主方法public  int process(Conference[]programs,int done,int timeLine){//出口条件:判断所有的事务是否都已完成if( 0==programs.length){return 0;}//继承上面做的事务数量int max=done;//循环:处理当前事务,并判断下面的事务(以当前事务为第一个事务,不断进行暴力枚举)for(int i=0;i=timeLine){//没有需要处理的,直接跨入下一个Conference[] conferences = copyButExpect(programs, i);max=Math.max(max,  process(conferences, done+1, programs[i].end));}}return max;}//创建获取新数组的方法public Conference[] copyButExpect(Conference[]programs,int i){//创建新的数组Conference[] arr=new Conference[programs.length-1];int count=0;//定义计数器for(int k=0;k< programs.length;++i){if(k!=i){arr[count++]=programs[k];}}return arr;}}
  1. 路灯问题

package greedy;import java.util.HashSet;/*** @author tongchen* @create 2023-03-09 9:01* 思路:循环处理灯:判断当前位置为X的时候不做选择,当前位置是.的时候选择放入和不放入*/
public class LightsForViolence {public static void main(String[] args) {}public int process(char[]places, int index, HashSetlights){//当index走到最后的时候,从头到尾依次判断这次的放入灯的策略是否正确if(index==places.length){//遍历检查有效性for (int i = 0; i < places.length; i++) {if(places[i]!='X'){if(lights.contains(i-1)&&lights.contains(i)&&lights.contains(i+1)){//这种情况不合理return  Integer.MAX_VALUE;}}}return lights.size();}else {//没有走到最后int no=process(places, index+1, lights);int yes=Integer.MAX_VALUE;if(places[index]=='.'){lights.add(index);yes=process(places, index+1, lights);}return Math.min(yes,no);}}}

这三个题目只是贪心问题中的冰山一角:

另外我还做了其他的一些关于贪心问题的题目,并总结了贪心策略,希望能给大家带来一些启发。

链接如下:

三.总结概括

我们通过上面的例子更能清楚的感受到不同题目所采用的的贪心算法的多样性和灵活性,在一定程度上很难在其中找到固定的解法,但是我们仍能从其中找到一些普适的规律:很多贪心题目都能在进行特定的排序或者将其放入按照某些属性进行排序的大跟堆和小根堆中,往往有可能能够找到正确的贪心策略。

相关内容

热门资讯

延续百年的艺术生命 转自:光明日报    布勒东(1896—1966)资料图片    马格利特作品《人类的境况》资料图片...
崇义章源钨业股份有限公司关于参... 证券代码:002378 证券简称:章源钨业 公告编号:2025-030崇义章源钨业股份有限公司关于...
成都市新筑路桥机械股份有限公司... 证券代码:002480 证券简称:新筑股份 公告编号:2025-037成都市新筑路桥机械股份有限公...
中粮糖业控股股份有限公司关于参... 证券代码:600737 证券简称:中粮糖业 公告编号:2025-014中粮糖业控股股份有限公司关于...
获格莱美四项提名歌手参加我是歌... 【#获格莱美四项提名歌手参加我是歌手# #3名国际歌手谈参加我是歌手#】5月14日,#歌手首发阵容官...
教育部禁止中小学生用AI写作业... 【#教育部禁止中小学生用AI写作业##教育部给学生的AI依赖立规矩#】5月12日,教育部基础教育教学...
中国建筑全资子公司新增一项41... (转自:快查一企业中标了)快查APP显示,中国建筑相关公司中国建筑一局(集团)有限公司于2025年5...
收盘:美股涨跌不一 道指连续第... 查看最新行情   北京时间5月15日凌晨,美股周三收盘涨跌不...
河南蓝天燃气股份有限公司关于使... 证券代码:605368 证券简称:蓝天燃气 公告编号:2025-034转债代码:111017 转债...
秘鲁总统任命前司法部长阿拉纳为... 秘鲁总统博鲁阿尔特(左)和新任总理爱德华多·阿拉纳(右)在宣誓仪式上新华社利马5月14日消息,秘鲁总...
原油:WTI下跌 美国原油库存...   原油下跌,此前有政府报告显示,美国原油库存创两个月来最大增幅,抵消了世界两大经济体贸易战暂停带来...
长江精工钢结构(集团)股份有限... 股票简称:精工钢构 股票代码:600496 编号:临2025-065转债简称:精工转债 转债代码...
山东高速路桥集团股份有限公司关... 证券代码:000498 证券简称:山东路桥 公告编号:2025-42山东高速路桥集团股份有限公司关...
丽珠医药集团股份有限公司关于回... 证券代码:000513、01513 证券简称:丽珠集团、丽珠医药 公告编号:2025-042丽珠医药...
因存在安全隐患,福特公司召回约... 央视记者当地时间5月14日获悉,福特汽车公司宣布,由于存在可能导致车辆在行驶过程中丧失制动功能、增加...
“土原料”变“潮产品” 青海兄弟乳业生物科技有限公司张成龙获“2025 IMW世界甜品巧克力&手工冰淇淋大赛暨2025意大利...
顺我者富 逆我者贫——解读特朗...   美国众议院共和党提出的新税收法案草案中,富人和企业投资者明显受益,而移民、顶尖私校等被特朗普长期...
青稞“链”上黄金道 产业升级加... 5月13日,海东市互助土族自治县青稞产业园内,青稞香飘满链。生产线轰鸣声中,金黄青稞粒经低温烘焙化作...
青海多措并举维护广告市场良好秩... 本报讯 (记者 董洁) 5月14日,记者从青海省市场监督管理局获悉,为切实维护全省广告市场秩序,保障...
厦门钨业股份有限公司关于向控股... 证券代码:600549 证券简称:厦门钨业 公告编号:临-2025-046厦门钨业股份有限公司关于...