贪心算法策略实现

贪心算法

贪心算法:基于某种情况进行一个排序。 贪心算法得到的是优良解,而非全局最优解。需要证明局部最优解 == 全局最优解

经典贪心算法 —— 会议问题

对于这个问题 ,我们提出贪心策略:

策略1:按照会议的持续时间长短来排序。持续时间短的会议优先安排

我们可以举出反例:蓝色方案安排的场次比绿色方案安排的场次少

策略2:按照会议的开始时间早晚来排序。开始时间早的会议优先安排

我们可以举出反例:蓝色方案安排的场次比绿色方案安排的场次少

.......

策略n:按照会议的结束时间早晚来排序。结束时间早的会议优先安排

这个策略是正确的,先上代码

package greedyalgorithms;import java.util.Arrays;
import java.util.Comparator;public class ScheduleProgram {class Progame {//会议int start;int end;public Progame(int start, int end) {this.start = start;this.end = end;}}public static class ProgameComparator implements Comparator<Progame> {//按结束时间从早到晚排序@Overridepublic int compare(Progame o1, Progame o2) {return o1.end - o2.end;//o1的结束时间比o2的结束时间晚,o2排前面//返回-1(或负数),表示不需要交换o1和o2的位置,o1排在o2前面//返回1(或正数),表示需要交换o1和o2的位置,o2排在o1前面}}//progames:需要安排的会议,timePoint:目前的时间点public int bestArrange(Progame[] progames, int timePoint) {Arrays.sort(progames, new ProgameComparator());//按照ProgameComparator比较器定义的compare()方法来排序int result = 0;for (int i = 0; i < progames.length; i++) {if(timePoint <= progames[i].start){//此时时间 <= 会议的开始时间result++;//安排好的会议的个数++timePoint = progames[i].end;//时间来到会议的结束时间}}return result;}
}

对于这个策略,我们不能够轻松举出反例,但证明需要使用严格复杂的数学证明

贪心算法在笔试时的解题套路

1、准备暴力枚举、全排列的模板,贪心算法的最优解一定在全排列之中

2、贪心策略类题目,是一句某个标准排序或是放在堆里各自排序,举出n多个比较策略。此时容易举出反例的比较策略可以直接pass

3、用策略X结合随机大样本跑对数器。如果某个策略几千万次的随机样本都相同,那么这个比较策略就是正确的

什么是对数器?对数器的作用是什么?-CSDN博客

贪心策略实现

切分金条的最小分割代价

哈夫曼编码问题

从反方向考虑,已经切好的数组如何合并使得花费最小,花费的金额为合并的数值

贪心策略:每次挑代价最小的2个数来结合

如果有一组数组:arr = {2, 3, 4, 7, 9, 2}

将数组放入小根堆中arr = {2, 2, 3, 4, 7, 9}
前两个数相加arr = {4, 3, 4, 7, 9}
排序arr = {3, 4, 4, 7, 9}
前两个数相加arr = {7, 4, 7, 9}
排序arr = {4, 7, 7, 9}
前两个数相加arr = {11, 7, 9}
排序arr = {7, 9, 11}
前两个数相加arr = {16, 11}
排序arr = {16, 11}
两个数相加arr = {27}
package greedyalgorithms;import java.util.PriorityQueue;public class LessMoneySplitGold {public static int lessMoney(int[] arr) {PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();//默认小根堆for (int i = 0; i < arr.length; i++) {priorityQueue.add(arr[i]);//将数组全部放入小根堆}int temp = 0;while (priorityQueue.size() > 1) {temp = priorityQueue.poll() + priorityQueue.poll();//弹出两个相加priorityQueue.add(temp);//加回去,排序}return priorityQueue.poll();//最后小根堆中只有一个数即为结果}
}

做项目获得的最大收益

costs[]:花费数组,profits[]: 利润数组

这里的花费仅仅表示做项目的门槛,因为在实际题目的计算中并没有减去项目花费的数

实现解析

一组项目:<花费,利润>

<2,3>,  <1,4>,  <1,1>,  <2,7>.,  <3,2>,  <4,10>

将项目放入一个以花费为依据的小根堆中,其中,利润的大小不考虑

小根堆中的项目表示都是锁住(不可做)的状态

小根堆中:<1,4>,  <1,1>,   <2,3>,  <2,7>.,  <3,2>,  <4,10>

依据初始资金m,解锁所有花费小于等于m的项目放到一个以利润为依据的大根堆中,其中,花费的大小不考虑

大根堆中的项目表示解锁(可做)的状态

m = 1; 大根堆中:<1,4>,  <1,1>

大根堆抛出第一个项目,初始资金更新为m+该项目的利润

依据新的初始资金m,在小根堆中解锁项目,在大根堆中抛出,更新利润 .......

直到到达指定的项目数k停止

此外,还有另一种情况。当没有达到指定的项目数k,但某一时刻的初始资金比较少,不能够解锁小根堆中剩下的所有项目,此时只能提前返回当前的资金m

package greedyalgorithms;import java.util.*;public class FindMaxmizedCapital {int M = 0;//初始资金int K = 0;//表示最多做k个项目class Program {public int cost;//花费public int profit;//利润public Program(int cost, int profit) {this.cost = cost;this.profit = profit;}}public int findMaxmizedCapital(List<Program> programs, int M, int K) {PriorityQueue<Program> minCostPQ = new PriorityQueue(new MinCostComparator());PriorityQueue<Program> maxProfitPQ = new PriorityQueue(new MaxProfitComparator());//全部放入小根堆中锁定for (Program pr : programs) {minCostPQ.add(pr);}for (int i = 0; i < K; i++) {//peek(): 获取元素但不删除队列首元素while (!minCostPQ.isEmpty() && minCostPQ.peek().cost <= M) {maxProfitPQ.add(minCostPQ.poll());//放入大根堆中,解锁}//更新初始资金M += maxProfitPQ.poll().profit;//当没有达到指定的项目数k,但某一时刻的初始资金比较少,不能够解锁小根堆中剩下的所有项目,此时只能提前返回当前的资金mif (maxProfitPQ.isEmpty()) {break;}}return M;}class MinCostComparator implements Comparator<Program> {@Overridepublic int compare(Program o1, Program o2) {return o1.cost - o2.cost;//compare()方法比较o1,o2的大小//正序:当o1<o2时return -1,o1=o2时return 0,o1>o2时return 1}}class MaxProfitComparator implements Comparator<Program> {@Overridepublic int compare(Program o1, Program o2) {return o2.profit - o1.profit;}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/229981.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高效办公:如何使用视频剪辑工具批量转码,mp4视频到TS视频

在视频处理过程中&#xff0c;转码是一项常见的任务。将MP4视频转换为TS视频可以提供许多优势&#xff0c;包括更好的兼容性、更广泛的设备和平台支持以及更高的视频质量。然而&#xff0c;手动转码大量视频文件可能会非常耗时且效率低下。为了实现高效办公&#xff0c;可以使用…

RabbitMQ快速学习之WorkQueues模型、三种交换机、消息转换器(基于SpringBoot)

文章目录 前言一、WorkQueues模型消息发送消息接收能者多劳 二、交换机类型1.Fanout交换机消息发送消息接收 2.Direct交换机消息接收消息发送 3.Topic交换机消息发送消息接收 三、编程式声明队列和交换机fanout示例direct示例基于注解 四、消息转换器总结 前言 WorkQueues模型…

亚马逊云科技 re:Invent 2023:引领科技前沿,探索未来云计算之窗

文章目录 一、前言二、什么是亚马逊云科技 re:Invent&#xff1f;三、亚马逊云科技 re:Invent 2023 将于何时何地举行四、亚马逊云科技 re:Invent 2023 有什么内容&#xff1f;4.1 亚马逊云科技 re:Invent 2023 主题演讲4.2 亚马逊云科技行业专家探实战 五、更多亚马逊云科技活…

人工智能原理复习--知识表示(二)

文章目录 上一篇产生式表示法推理方式 结构化表示语义网络语义网络表示知识的方法和步骤应用题目 框架表示法下一篇 上一篇 人工智能原理复习–知识表示&#xff08;一&#xff09; 产生式表示法 把推理和行为的过程用产生式规则表示&#xff0c;所以又称基于规则的系统。 产…

哈希_快乐数

//编写一个算法来判断一个数 n 是不是快乐数。 // // 「快乐数」 定义为&#xff1a; // // // 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。 // 然后重复这个过程直到这个数变为 1&#xff0c;也可能是 无限循环 但始终变不到 1。 // 如果…

LTD253次升级 | 官网“活动“增报名 • 名片展示个人简介 • 合伙人设置个性邀请码

1、活动类型支持报名&#xff1b; 2、产品详情页支持房产类型产品的地图显示&#xff1b; 3、官微名片独立版支持个人简介&#xff1b; 4、多语言系统支持挪威语&#xff1b; 5、极速官微首页提速、合伙人页面优化&#xff1b; 6、 已知问题优化与修复&#xff1b; 01网站编辑器…

陪诊系统:基于自然语言处理的患者沟通创新

医疗领域的数字化转型正日益引入创新技术&#xff0c;其中基于自然语言处理&#xff08;NLP&#xff09;的陪诊系统成为提升患者沟通的一项关键技术。本文将深入研究这一领域&#xff0c;介绍陪诊系统如何借助NLP实现患者沟通的创新&#xff0c;并提供一个简单的Python代码示例…

模拟算法【1】

文章目录 &#x1f600;1576. 替换所有的问号&#x1f606;题目&#x1f929;算法原理&#x1f642;代码实现 &#x1f60a;495.提莫攻击&#x1fae0;题目&#x1f609;算法原理&#x1f917;代码实现 模拟算法 通俗的来说&#xff0c;模拟算法就是依葫芦画瓢&#xff0c;将题…

java科学计数法表示数值

Background 大多数计算器及计算机程序用科学记数法显示非常大和非常小的结果&#xff1b;但很多时候&#xff0c;我们需要做一个统一&#xff0c;要么全部以科学计数法输出&#xff0c;要么就全部显示为普通计数。注意&#xff1a;这里对大于等于1的数据做了特殊处理&#xff0…

第20 章 多线程

20.1线程简介. 20.2创建线程 2.1继承Thread类 Thread 类是java.lang包中的一个类&#xff0c;从这个类中实例化的对象代表线程&#xff0c;程序员启动一个新线程需要建立Thread 实例。Thread类中常用的两个构造方法如下: public Thread():创建一个新的线程对象。 public Thre…

uView ui 1x uniapp 表格table行内容长度不一导致高度不统一而出现的不对齐问题

问题 因为td单元格内空长度不定导致行单元格未对齐 解决&#xff1a; 重置td的高度&#xff1a;height:100% 改为height:auto !import <u-table><u-tr v-for"(item,index) in Lineinfo.Cust_Name" ><u-td style"height: auto !important;back…

基于YOLOv8深度学习的PCB板缺陷检测系统【python源码+Pyqt5界面+数据集+训练代码】目标检测

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能AI、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推荐--…