贪心算法例题
来源:互联网 发布:数据精灵稳定版源 编辑:程序博客网 时间:2024/06/16 11:09
简介
贪心算法(greedy)分阶段地工作,在每一个阶段都可以认为所做的决定是最好的,而不用考虑后果。这就意味着得到的是局部最优解决方案,当算法结束时,如果一个一个局部最优解能组成全局最优解决,那么就说明这个算法是正确的;如果不是,则此算法的到的结果就是一个次优解。因此,如果使用贪婪算法得到问题的最优解,那么问题就必须满足一定的条件。
找零钱问题
这个问题在我们的日常生活中非常普遍了。假设1元、2元、5元、10元、20元、50元、100元的纸币。现在要用这些钱来支付K元,至少要用多少张纸币?用贪心算法的思想,很显然,每一步尽可能用面值大的纸币即可。在日常生活中我们自然而然也是这么做的。在程序中已经事先将Value按照从大到小的顺序排好,第一次我们先取面值最大的,然后取次大的。。。。。。每次取都是从面额最大的开始取,获得局部最优解,而最终获得全局最优解。代码如下:
public class Greedy { public List<Integer> change(int money,int[] limit){ //Arrays.sort(limit); List<Integer> result = new ArrayList<>(); int left = money; int i = 0; while(left>0){ if((left - limit[i])<0){ i++; }else { left -= limit[i]; result.add(limit[i]); } } return result; } public static void main(String[] args) { Greedy greedy = new Greedy(); int money = 96; int[] limit = {50,20,10,5,1}; List<Integer> change = greedy.change(money, limit); for (Integer integer : change) { System.out.println(integer); } }}/*50202051*/
背包问题
我们知道三种最基本的背包问题:零一背包,部分背包,完全背包。很容易证明,背包问题不能使用贪心算法。然而我们考虑这样一种背包问题:在选择物品i装入背包时,可以选择物品的一部分,而不一定要全部装入背包。这时便可以使用贪心算法求解了。计算每种物品的单位重量价值(性价比)作为贪心选择的依据指标,选择单位重量价值最高的物品,将尽可能多的该物品装入背包,依此策略一直地进行下去,直到背包装满为止。
class Goods{ int id;// 物体的序号 int w;// 物体的重量 int p;// 物体的价值}List<Goods> commonPackage( int[] w, int[] p, int m ){ List<Goods> goods = new ArrayList<>(); for ( int i=0; i<w.length; i++ ) { Goodss.add(new Goods(w[i],p[i])); } // 对性价比从高到低排序 Collections.sort(Goodss, new Comaprator<Goods>(){ int compare(Goods b1,Goods b2){ return b2.p/b2.w-b1.p/b1.w; } }); // 剩余重量 int rest = m; int i; // 存放结果 List<Goods> results = new ArrayList<>(); for(i=0; i<Goodss.size(); i++){ if ( rest<Goodss.get(i).w ) break; Goods curGoods = Goodss.get(i); results.add(curGoods); rest -= curGoods.w; } // 计算最后一个物体能放入的部分 Goods lastGoods = Goodss.get(i); results.add(new Goods(lastGoods.id,rest,(lastGoods.p*rest/lastGoods.w));}
小船过河问题
只有一艘船,能乘2人,船的运行速度为2人中较慢一人的速度,过去后还需一个人把船划回来,问把n个人运到对岸,最少需要多久。局部最优解是这样的:将最快的和次快的绑定在一起,然后最快的划船回来;再将最快的和次次块的一起,然后最快的回来。这样我们可以知道,这些局部最优解组成了全局最优解。证明如下:假设序号为i的人划船时间为ti,那么总时间=划船回来的时间+划船过去的时间,也就是t1+t2+。。。+tn+划船回来的时间。划船回来的总时间最短为n*最快的人的时间。
这里我写一下伪代码:
//从时间上从快到慢排序Arrays.sort(t[n]);for i=1 to n-1; //计算去的时间 sum + = t[i]; //计算回来的时间 back = (n-1)*t[0];totalTime = sum+back;
总结
我认为贪心算法其实是一种策略,对于某个问题使用某种策略去求得最优解。做题的时候,首先需要更具题目来判断,是否可以使用贪心算法来解决,判断依据就是:局部最优解是否能组成全局最优解决。如果能,就需要指定求局部最优解的策略,也就是选择的依据。是按照面值最大的先先选;还是按照速度最快的先走;亦或是按照性价比最高的先买?
- 贪心算法例题
- 贪心算法例题
- 算法设计例题:最优装载(贪心)
- 贪心算法基本思想和典型例题
- 贪心算法基本思想和典型例题
- 贪心算法例题:2072删数问题
- 贪心算法例题:2073活动选择问题
- 贪心算法例题:2075最少拦截系统
- 贪心算法例题:2052装船问题
- 贪心算法例题:2850商人小鑫
- 贪心算法例题:2851懒虫小鑫
- 贪心算法例题:杭电Saving HDU
- 贪心算法例题:2079悼念512汶川大地震遇难同胞
- python——三道贪心算法例题
- 【贪心例题专题】&贪心~越多越好哟~&
- 贪心例题 翻纸牌
- 贪心例题集
- 算法例题
- Spring Class Global Method
- Linux 安装 mysql
- Aras innovator: 如何制作一个itemtype的BOM结构
- python 列表操作(增删查)
- [比赛交流] AI法官
- 贪心算法例题
- AI 与区块链会碰撞出什么样的火花?要取代传统银行系统!?
- pytorch的tf.transpose
- Mysql无法创建外键的原因汇总
- 两分钟配置 HTTPS
- 在Linux中,如何找到并杀掉僵尸进程?
- linux下memcached安装以及启动
- 多线程,就是这么简单!
- PHP 文件系统(读取文件内容)