贪心算法

  • 1. 什么是贪心算法?
  • 二、贪心算法的基本思路
  • 三、贪心算法适用的问题
  • 四、贪心算法的实现框架
  • 五、贪心策略的选择
  • 六、贪心算法的几个例子
    • 1. 纸币找零问题
    • 2. 背包问题

1. 什么是贪心算法?

贪心算法,又称贪婪算法(Greedy Algorithm),是指在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优解出发来考虑,它所做出的仅是在某种意义上的局部最优解。

贪婪算法是一种分阶段的工作,在每一个阶段,可以认为所做决定是最好的,而不考虑将来的后果。这种“眼下能够拿到的就拿”的策略是这类算法名称的来源。

贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择。必须注意的是,贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关。所以对所采用的贪心策略一定要仔细分析其是否满足无后效性。

二、贪心算法的基本思路

  1. 建立数学模型来描述问题。
  2. 把求解的问题分成若干个子问题。
  3. 对每一子问题求解,得到子问题的局部最优解。
  4. 把子问题的解局部最优解合成原来解问题的一个解。

三、贪心算法适用的问题

贪心策略适用的前提是:局部最优策略能导致产生全局最优解。也就是当算法终止的时候,局部最优等于全局最优。

四、贪心算法的实现框架

从问题的某一初始解出发;
while (能朝给定总目标前进一步)
{
利用可行的决策,求出可行解的一个解元素;
}
由所有解元素组合成问题的一个可行解;

五、贪心策略的选择

因为用贪心算法只能通过解局部最优解的策略来达到全局最优解,因此,一定要注意判断问题是否适合采用贪心算法策略,找到的解是否一定是问题的最优解。
如果确定可以使用贪心算法,那一定要选择合适的贪心策略;

六、贪心算法的几个例子

1. 纸币找零问题

假设1元、2元、5元、10元、20元、50元、100元的纸币,张数不限制,现在要用来支付K元,至少要多少张纸币?

/**  * 钱币找零问题** @param money the money*/
public static void greedyGiveMoney(int money) {System.out.println("需要找零: " + money);int[] moneyLevel = {1, 5, 10, 20, 50, 100}; // 把所有钱放到数组中for (int i = moneyLevel.length - 1; i >= 0; i--) { // 先从面值最大的钱开始取,依次减小面值int num = money/ moneyLevel[i];      // 纸张数目int mod = money % moneyLevel[i];  // 剩余的钱 money = mod;if (num > 0) {  // 如果这个面值的纸张数目不为0System.out.println("需要" + num + "张" + moneyLevel[i] + "块的");}}
}

(1)如果不限制纸币的金额,那这种情况还适合用贪心算法么。比如1元,2元,3元,4元,8元,15元的纸币,用来支付K元,至少多少张纸币?

经我们分析,这种情况是不适合用贪心算法的,因为我们上面提供的贪心策略不是最优解。比如,纸币1元,5元,6元,要支付10元的话,按照上面的算法,至少需要1张6元的,4张1元的,而实际上最优的应该是2张5元的。

(2)如果限制纸币的张数,那这种情况还适合用贪心算法么。比如1元10张,2元20张,5元1张,用来支付K元,至少多少张纸币?

同样,仔细想一下,就知道这种情况也是不适合用贪心算法的。比如1元10张,20元5张,50元1张,那用来支付60元,按照上面的算法,至少需要1张50元,10张1元,而实际上使用3张20元的即可;

(3)所以贪心算法是一种在某种范围内,局部最优的算法。

2. 背包问题

有一个背包,背包容量是W=150。有7个物品,每个物品有各自的重量和价值,每个物品有一件。要求尽可能让装入背包中的物品总价值最大,但不能超过总容量。

物品 A B C D E F G
重量 35 30 60 50 40 10 25
价值 10 40 30 50 35 40 30

我们很容易想到使用贪心算法来解决这个问题,那我们考虑一下贪心策略:

(1)每次挑选价值最大的物品放入背包,得到的结果是否最优?

(2)每次挑选所占重量最小的物品放入背包,得到的结果是否最优?

(3)每次选取单位重量价值最大的物品,得到的结果是否最优?

值得注意的是,贪心算法并不是完全不可以使用,贪心策略一旦经过证明成立后,它就是一种高效的算法。但可惜的是,它需要证明后才能真正运用到题目的算法中。

以上问题使用贪心算法是解决不了的,而普通背包问题可以使用贪心算法来解决。这个问题是属于0-1背包问题,不过我们可以考虑使用动态规划来解决,那就是另一个问题了。

Java - 初探贪心算法(纸币找零,背包问题)相关推荐

  1. 贪心算法解决找零钱问题

    4.1 找零问题 问题描述: 设有50.20.10.5.1.0.5.0.1等面额的零钱,顾 客购物花了n元,在支付(n / 100 + 1) * 100元后,收银员应如何找 零,才能使找回的钱数最少. ...

  2. C++贪心算法求解找零钱问题(很形象)

    贪心算法求解找零钱问题 1.什么是贪心算法? 贪心算法是一种策略,总是做出在当前看来是最好的选择,总结出来几个字:寻找最优解 举个例子来说就是:"有一个只能往前走的果园,里边有各种水果让你免 ...

  3. java贪心,java实现贪心算法

    并证明了贪心算法解决此问题的有效性,且进行了实例验证,并进 行了复杂度分析,此算法是解决资源组合规划问题较好的方法. 关键词:贪心算法;java 程序;复杂度分析;...... 数据结构与算法 实验名 ...

  4. 贪心算法之找硬币问题

    贪心算法之找硬币问题 题目: 假设有面值为5元.2元.1元.5角.2角.1角(折半查找排序)的货币,需要找给顾客4元6角现金,为使付出的货币的数量最少,如何付款? 贪心算法的思想: 只根据当前的信息就 ...

  5. 算法基础(Java)--贪心算法

    前言 前面简单的介绍了八大经典排序算法,此文将要介绍贪心算法,并介绍一些常见贪心算法题目. 1. 贪心算法的概念 所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最 ...

  6. 动态规划在求解硬币问题中的应用(JAVA)--币制最大化、找零问题、硬币收集问题

    动态规划:这种算法思想多用来求解最优化问题,因此这里存在一个最优化法则,法则指出最优化问题任一实例的最优解,都是由其子实例的最优解构成的.一般来说,自底向上的动态规划更容易设计,但是带有记忆功能的自顶 ...

  7. 贪心算法1——找零钱问题

    贪心算法是一种不追求最优解,只希望找到较为满意解的方法.贪心算法省去了为找最优解要穷尽所有可能而必须耗费的大量时间,因此它一般可以快速得到比较满意的解. 贪心算法常以当前情况做最优选择,而不考虑各种可 ...

  8. c语言贪心算法零钱问题,贪心算法(2)——找零钱问题

    一.找零钱问题 例题1: 有 1 元,5元,10元,20元,100元,200元的钞票无穷多张.现在使用这些钞票支付X元,最少需要多少张钞票. X = 628 最佳支付方法: 3张200块的,1张20块 ...

  9. Java使用动态规划算法思想解决01背包问题

    Java使用动态规划算法思想解决背包问题 背包问题是一种组合优化的NP完全问题.问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高 动 ...

最新文章

  1. C++巧用do...while(0)
  2. 自动构建工具Grunt
  3. 【设计模式】代理模式 ( 动态代理 | 模拟 Java 虚拟机生成对应的 代理对象 类 )
  4. jQuery里面的addClass讲解
  5. 第七章 脚本参数的传递
  6. python tkinter画笑脸_Python3 tkinter基础 Canvas create_polygon 画三角形
  7. 二元函数洛必达求极限_(整理)二元函数极限的求法.
  8. 蓝桥杯试题及答案分享(Python版)
  9. poj 2632 Crashing Robots
  10. x64dbg安装xAnalyzer插件失败问题解决
  11. 2022SWJTUACM新秀杯题解
  12. 打算在县城“买”片地
  13. 植树节的微信软文如何写?素材加文案帮你分分钟搞定!
  14. ps基础入门2-图层样式
  15. cu3er 3D幻灯切换效果 div被遮住的解决方法
  16. bzoj4275[ONTAK2015]Badania naukowe DP
  17. 哈尔滨工业大学2022计算机系统大作业
  18. 未明学院:找实习是门“玄学”?学姐这份券商、咨询、500强企业实习经验收藏好!
  19. StringRedisTemplate与RedisTemplate异同源码探秘
  20. 买《Python Web全栈工程师》专题视频课程送纸质图书

热门文章

  1. 直播电商要处理好五个关系
  2. 微信小程序的特点是什么?
  3. A卡比N卡画质好,真有此事吗?
  4. 那些高曝光的Annotation(@ComponentScan、@PropertySource与@PropertySources、@Import与ImportResource)
  5. Matlab图形加网格
  6. Java-泛型T T与T的用法
  7. Javascript的基础语法(标识符/变量)
  8. java run 方法_java线程中的run()方法能有几个啊?
  9. bluez 设置绑定pin码_「RT-Thread笔记」IO设备模型及PIN设备
  10. vue - rimraf