Java - 初探贪心算法(纸币找零,背包问题)
贪心算法
- 1. 什么是贪心算法?
- 二、贪心算法的基本思路
- 三、贪心算法适用的问题
- 四、贪心算法的实现框架
- 五、贪心策略的选择
- 六、贪心算法的几个例子
- 1. 纸币找零问题
- 2. 背包问题
1. 什么是贪心算法?
贪心算法,又称贪婪算法(Greedy Algorithm),是指在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优解出发来考虑,它所做出的仅是在某种意义上的局部最优解。
贪婪算法是一种分阶段的工作,在每一个阶段,可以认为所做决定是最好的,而不考虑将来的后果。这种“眼下能够拿到的就拿”的策略是这类算法名称的来源。
贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择。必须注意的是,贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关。所以对所采用的贪心策略一定要仔细分析其是否满足无后效性。
二、贪心算法的基本思路
- 建立数学模型来描述问题。
- 把求解的问题分成若干个子问题。
- 对每一子问题求解,得到子问题的局部最优解。
- 把子问题的解局部最优解合成原来解问题的一个解。
三、贪心算法适用的问题
贪心策略适用的前提是:局部最优策略能导致产生全局最优解。也就是当算法终止的时候,局部最优等于全局最优。
四、贪心算法的实现框架
从问题的某一初始解出发;
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 - 初探贪心算法(纸币找零,背包问题)相关推荐
- 贪心算法解决找零钱问题
4.1 找零问题 问题描述: 设有50.20.10.5.1.0.5.0.1等面额的零钱,顾 客购物花了n元,在支付(n / 100 + 1) * 100元后,收银员应如何找 零,才能使找回的钱数最少. ...
- C++贪心算法求解找零钱问题(很形象)
贪心算法求解找零钱问题 1.什么是贪心算法? 贪心算法是一种策略,总是做出在当前看来是最好的选择,总结出来几个字:寻找最优解 举个例子来说就是:"有一个只能往前走的果园,里边有各种水果让你免 ...
- java贪心,java实现贪心算法
并证明了贪心算法解决此问题的有效性,且进行了实例验证,并进 行了复杂度分析,此算法是解决资源组合规划问题较好的方法. 关键词:贪心算法;java 程序;复杂度分析;...... 数据结构与算法 实验名 ...
- 贪心算法之找硬币问题
贪心算法之找硬币问题 题目: 假设有面值为5元.2元.1元.5角.2角.1角(折半查找排序)的货币,需要找给顾客4元6角现金,为使付出的货币的数量最少,如何付款? 贪心算法的思想: 只根据当前的信息就 ...
- 算法基础(Java)--贪心算法
前言 前面简单的介绍了八大经典排序算法,此文将要介绍贪心算法,并介绍一些常见贪心算法题目. 1. 贪心算法的概念 所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最 ...
- 动态规划在求解硬币问题中的应用(JAVA)--币制最大化、找零问题、硬币收集问题
动态规划:这种算法思想多用来求解最优化问题,因此这里存在一个最优化法则,法则指出最优化问题任一实例的最优解,都是由其子实例的最优解构成的.一般来说,自底向上的动态规划更容易设计,但是带有记忆功能的自顶 ...
- 贪心算法1——找零钱问题
贪心算法是一种不追求最优解,只希望找到较为满意解的方法.贪心算法省去了为找最优解要穷尽所有可能而必须耗费的大量时间,因此它一般可以快速得到比较满意的解. 贪心算法常以当前情况做最优选择,而不考虑各种可 ...
- c语言贪心算法零钱问题,贪心算法(2)——找零钱问题
一.找零钱问题 例题1: 有 1 元,5元,10元,20元,100元,200元的钞票无穷多张.现在使用这些钞票支付X元,最少需要多少张钞票. X = 628 最佳支付方法: 3张200块的,1张20块 ...
- Java使用动态规划算法思想解决01背包问题
Java使用动态规划算法思想解决背包问题 背包问题是一种组合优化的NP完全问题.问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高 动 ...
最新文章
- C++巧用do...while(0)
- 自动构建工具Grunt
- 【设计模式】代理模式 ( 动态代理 | 模拟 Java 虚拟机生成对应的 代理对象 类 )
- jQuery里面的addClass讲解
- 第七章 脚本参数的传递
- python tkinter画笑脸_Python3 tkinter基础 Canvas create_polygon 画三角形
- 二元函数洛必达求极限_(整理)二元函数极限的求法.
- 蓝桥杯试题及答案分享(Python版)
- poj 2632 Crashing Robots
- x64dbg安装xAnalyzer插件失败问题解决
- 2022SWJTUACM新秀杯题解
- 打算在县城“买”片地
- 植树节的微信软文如何写?素材加文案帮你分分钟搞定!
- ps基础入门2-图层样式
- cu3er 3D幻灯切换效果 div被遮住的解决方法
- bzoj4275[ONTAK2015]Badania naukowe DP
- 哈尔滨工业大学2022计算机系统大作业
- 未明学院:找实习是门“玄学”?学姐这份券商、咨询、500强企业实习经验收藏好!
- StringRedisTemplate与RedisTemplate异同源码探秘
- 买《Python Web全栈工程师》专题视频课程送纸质图书
热门文章
- 直播电商要处理好五个关系
- 微信小程序的特点是什么?
- A卡比N卡画质好,真有此事吗?
- 那些高曝光的Annotation(@ComponentScan、@PropertySource与@PropertySources、@Import与ImportResource)
- Matlab图形加网格
- Java-泛型T T与T的用法
- Javascript的基础语法(标识符/变量)
- java run 方法_java线程中的run()方法能有几个啊?
- bluez 设置绑定pin码_「RT-Thread笔记」IO设备模型及PIN设备
- vue - rimraf