贪心算法的全部讲解(贪心选择性和贪心子结构)
贪心算法
- 贪心算法的基本概念
- 贪心算法的适用范围
- 贪心算法的设计步骤
- 贪心算法的题目讲解
贪心算法的基本概念
贪心算法与枚举法的不同之处在于每个子问题都选择最优的情况,然后向下继续进行,且不能回溯,枚举法是将所有情况都考虑然后选出最优的情况。
贪心算法,在对问题求解时,不从整体考虑,而是采用一叶障目的选择方式,只选择某种意义上的局部最优解。并且,贪心算法是没有固定的模板可以遵循的,每个题目都有不同的贪心策略,所以算法设计的关键就是贪心策略的选择。
贪心算法有一个必须要注意的事情。贪心算法对于问题的要求是,所有的选择必须是无后效性的,即当前的选择,不能影响后续选择对于结果的影响。
贪心算法主要适用于最优化问题,如:MST
问题。有时候贪心算法并不能得到最优答案,但是能得到精确答案的近似答案。有时可以辅助其他算法得到不是那么精确的结果。
贪心算法的适用范围
符合贪心策略:
所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别。
所谓的贪心选择性质就是,该问题的每一步选择都在选择最优的情况下能够导致最终问题的答案也是最优。
或者说是无后效性,如果该问题的每一步选择都对后续的选择没有影响,就可以是应用贪心算法。
贪心算法的设计步骤
按照定义设计:
1.证明原问题的最优解之一可以由贪心选择得到。
2.将最优化问题转化为这样一个问题,即先做出选择,再解决剩下的一个子问题。
3.对每一子问题一一求解,得到子问题的局部最优解;
4.把子问题的解局部最优解合成原来解问题的一个解
贪心算法的题目讲解
题目如下:
(第一题)
假设商店老板需要找零 n 元钱。钱币的面额有:100 元、50 元、20 元、5 元、1 元、如何找零使得所需钱币的数量最少?注意:n 可能为 0,也能为几百元(别问,问就是来着里微信提现来了)
解题思路:
假设需要找n1个100、n2个50、n3个20、n4个5、n5个1
如果可以找到大面额的硬币就使用大面额的,这样可以减少使用多张小面额的硬币,因此我们尽可能的先找出n1然后n2.。。。n5
代码:
import java.util.Scanner;public class One_36 {static int[] a=new int[]{100,50,20,5,1};//用来存放每一种纸币的数量static int[] b=new int[5];//写change函数来求解static void Change(int N) {for (int i = 0; i < 5; i++) {b[i]=N/a[i];N=N%a[i];}}public static void main( String []args) {Scanner sc=new Scanner(System.in);int N=sc.nextInt();Change(N);//输出结果for (int i = 0; i <5; i++) System.out.println(a[i]+":"+b[i]);}
}
(第二题)
小 B 的宿舍楼沿着走廊南北向的两边各有 200 个房间。如图所示:[房间1][房间3][房间5][房间7][房间9 ]...[房间399]
----------------------------------------------走廊
----------------------------------------------
[房间2][房间4][房间6][房间8][房间10]...[房间400]最近,由于转专业和专业分流的原因,宿舍将迎来新的调整,以便组成新的班级后方便管理。但是由于走廊狭窄,走廊里只能通过两个搬运的物品(可以同向也可以反向),因此必须指定高效的搬运计划。老师给了每位同学下达了以下要求,让同学们体现收拾好行李,然后给每位同学 10 分钟的时间搬运。当房间 i 搬运行李到 j 时,i 与 j 之间的走廊都会被占用,但是可以容纳两个不同同学同时搬运。所以,10 分钟之内同一段走廊最多两个人同时搬运,不重叠的走廊也可以同时搬运。小 B 的老师是个数学老师,经过运筹学一通计算他得到了最优的搬运计划。虽然计划不唯一,但是最优值唯一,请问这个最短时间是多少?
解题思路:
可以把走廊看成一段一段的小节,这样可以求出每一节走廊的占有情况。找出占用次数最多的小节,由于每次可以两个同学占用同一小节,所有此时最少的时间就是最多的次数/2,如果有余数+1。将最终的结果乘以10就是最后的所有时间。
样例输入:
输入解法:
输入数据有 T 组测试例,在第一行给出测试例个数 T。
每个测试例的第一行是一个整数 N(1≤N≤200),表示要搬运行李的人数。接下来 N 行,每行两个正整数 s 和 t,表示一个人,将行李是从房间号码 s 移到到房间号码 t。
输入样例:
3
4
10 20
30 40
50 60
70 80
2
1 3
2 200
3
10 100
20 80
30 50
代码:
import java.util.Scanner;
public class One_38{public static void main(String[] args) {Scanner in = new Scanner(System.in);
//搬运次数int N;//每次搬运的起点和终点int from, to;int maxAns = 0;int T;T = in.nextInt();while (T > 0) {T--;N = in.nextInt();int[] move = new int[200];for (int i = 0; i < N; i++) {from=in.nextInt();to=in.nextInt();
//将房间号映射为走廊号from = (from - 1) / 2;to = (to - 1) / 2;
//确保from<toif (from > to) {int temp = from;from = to;to = temp;}//统计占用走廊情况,并统计最大值for (int j = from; j <= to; j++) {move[j]++;maxAns = Math.max(maxAns, move[j]);}}if (maxAns % 2 == 1) maxAns = maxAns / 2 + 1;else maxAns /=2;System.out.println( maxAns * 10);}}
}
(第三题)
小 B 同学呢,想去吃自助餐,但是他是那种比较节俭的的人,既不想浪费食物,又想尽可能吃的贵一点,他于是私下里做了调查。
小蓝餐厅的自助餐有 n 种食材,每种食材都有它的价格。
而且也能估计出每一份的重量,所以他列了一个表格。
红烧牛肉 30元 300g 油闷大虾 8元 5g 四喜丸子 4元 8g 三文鱼 5元 3g 排骨
18元 200g 麻辣兔头 20元 120g 高汤海参 40元 70g 扇贝粉丝 8元 32g 牛排
79元 240g …现在小 B 想知道在他到底最多吃多少钱的菜品。
假设自助餐厅的菜品供应同样的菜品每个人只能取一份。
小B的饭量假设为 C,单位为 g。
现在请你设计一个程序帮助小 B 计算他的最多吃了多少钱。
解题思路:
由于此题是可拆分背包问题,所以我们可以先吃单价最贵的物品,然后按价格依次递减的吃食物。
输入:
20 1000
1 22
2 43
123 214
12 2
123 432
21 223
22 16
77 49
34 78
34 9
43 677
21 34
23 23
12 56
332 56
21 99
123 545
389 33
12 999
23 88
输出
1204.114
代码:
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class One_40 {static class Food{public double w;public double v;public double aver;Food() {w=0;v=0;aver=0;}}static class mycmp implements Comparator<Food>{@Overridepublic int compare(Food a, Food b) {if (a.aver > b.aver) return -1;else return 1;//助记大于号就是从大到小排序,小于号就是从小到大排序}}static Food foods[]=new Food[1000];public static void main( String []args) {Scanner sc=new Scanner(System.in);int N=sc.nextInt();double C=sc.nextDouble();for (int i = 0; i <N; i++) {foods[i]=new Food();foods[i].v=sc.nextDouble();foods[i].w=sc.nextDouble();foods[i].aver=foods[i].v/foods[i].w;}Comparator cmp=new mycmp();Arrays.sort(foods,0,N,cmp);double Value=0;for (int i = 0; i <N&&C!=0; i++) {if (foods[i].w <= C) {Value = Value + foods[i].v;C = C - foods[i].w;} else {//直接将剩余的C加入即可Value = Value + C * foods[i].aver;C = 0;}}System.out.println(String.format("%.3f",Value));}}
贪心算法的全部讲解(贪心选择性和贪心子结构)相关推荐
- python贪心算法几个经典例子_关于贪心算法的一些探讨、经典问题的解决和三种典型的贪心算法算法(哈弗曼,Kruskal,Prim)的Python实现。...
贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解. 贪心算法不是对所有问题都能得到整体最优解,关键是 ...
- 汽车加油问题贪心算法c语言,汽车加油问题之贪心算法(全面分析)
一辆汽车加满油后可以行驶N千米.旅途中有若干个加油站.指出若要使沿途的加油次数最少,设计一个有 效的算法,指出应在那些加油站停靠加油.给出N,并以数组的形式给出加油站的个数及相邻距离,指出若要使沿途的 ...
- 算法设计与分析:贪心算法 - 排课问题(DP与贪心的区别与应用)
文章目录 前言 贪心算法概念 排课问题 问题描述与分析 动态规划求解 简化问题应用贪心算法 总结 本文参考UCAS卜东波老师算法设计与分析课程撰写 前言 前面两大章节的内容分治思想与动态规划暂时告一段 ...
- 贪心算法哈夫曼编码c语言,贪心算法详解:哈夫曼编码
理解贪心算法 贪心算法是一种算法思想,并不是一个具体的算法,因此我们用两个例子来理解什么样的问题适合用贪心算法解决. 例一 现在有一个能装 100g 物品的背包,和一些可拆分的物品(见表格),怎么装才 ...
- 嵌入式必会!C语言最常用的贪心算法就这么被攻略了
01 基本概念 贪心算法是指在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,只做出在某种意义上的局部最优解.贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的 ...
- lru调度算法例题_嵌入式必会!C语言最常用的贪心算法就这么被攻略了
01 基本概念 贪心算法是指在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,只做出在某种意义上的局部最优解.贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的 ...
- 基础算法 -- 贪心算法
题目描述: 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你可以尽可能地完成更多的交易(多次买卖一支股票). 注意:你不能同时参与多笔交易( ...
- 贪心算法(Greedy Algorithms)
1.贪心法的设计思想 贪心算法在解决问题的策略上目光短浅, 只根据当前已有的信息就做出选择,而且 一旦做出了选择,不管将来有什么结果,这个选择都不会改变.换言之,贪心法并不是从整体最优考虑,它所做出的 ...
- 三大算法之三:贪心算法及其例题详解
目录 零.前言 1.区分贪心算法和动态规划 1.动态规划 2.贪心算法 3.共通点 2.贪心算法得到最优解的条件 1.具有优化子结构 2.具有贪心选择性 3.任务安排问题 1.问题定义 2.优化子结构 ...
最新文章
- php 缺少参数,php - 如何验证JSON响应中是否缺少参数-Laravel 6 - 堆栈内存溢出
- go 切片slice删除元素的方法
- boost::fusion::for_each用法的测试程序
- 录制视频显示的视频角度和拍摄角度保持一致
- java算法题走楼梯,程序员必学算法「动态规划」:爬楼梯(完全背包解法)
- WinRAR 曝 19 年前重大漏洞,可完全控制电脑!| 附解决方法
- [LeetCode] 204. Count Primes
- linux打开cap文件,cap/pcap类文件无法用wireshark打开
- plc和计算机语言,PLC的编程语言具体有哪些
- 使用好压(HaoZip)软件打包EverEdit制作安装程序
- PR(Premiere) 鼓点节拍插件Beat Edit,打不开的原因
- 如何正确地准备KODI媒体文件
- android修改recovery菜单,安卓刷机Recovery菜单介绍刷入教程详解
- 什么是骨传导耳机,骨传导耳机有什么优缺点
- 使用Python读取raw格式图像并显示
- ping局域网里面全部的ip
- face_recognition IndexError: list index out of range
- 中小团队落地配置中心详解
- Python入门基础练习题
- 【Bootstrap学习笔记】12.轮播插件