贪心算法策略实现

news2024/11/29 4:30:10

贪心算法

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

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

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

策略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> {
        //按结束时间从早到晚排序
        @Override
        public 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,但某一时刻的初始资金比较少,不能够解锁小根堆中剩下的所有项目,此时只能提前返回当前的资金m
            if (maxProfitPQ.isEmpty()) {
                break;
            }
        }
        return M;
    }


    class MinCostComparator implements Comparator<Program> {
        @Override
        public 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> {
        @Override
        public int compare(Program o1, Program o2) {
            return o2.profit - o1.profit;
        }
    }


}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot : ch09 整合Redis

前言 当你的应用程序需要一个快速、可扩展的内存数据库时&#xff0c;Redis是一个非常流行的选择。通过将Redis与Spring Boot集成&#xff0c;你可以轻松地利用Redis的功能&#xff0c;例如缓存、会话存储和消息队列等&#xff0c;从而提升应用程序的性能和可伸缩性。 在本教…

FUSB302MPX USB Type-C端口控制器 芯片功能介绍

FUSB302MPX是带PD的可编USB Type-C控制器,除了默认的SRC功能,器件还支持可编程性低的DRP/SRC/SNK.器件具有USB Type-C检测包括附着/分离和取向.FUSB302MPX集成了USB BMC供电协议的物理层,允许高达100W功率和角色互换.BMC PD区块完全支持Type-C指标的替代接口.器件具有自主DRP切…

git rebase冲突说明(base\remote\local概念说明)

主线日志及修改 $ git log master -p commit 31213fad6150b9899c7e6b27b245aaa69d2fdcff (master) Author: Date: Tue Nov 28 10:19:53 2023 08004diff --git a/123.txt b/123.txt index 294d779..a712711 100644 --- a/123.txtb/123.txt-1,3 1,4 123 4^Mcommit a77b518156…

UE 事件分发机制(一) day9

观察者模式原理 观察者模式通常有观察者与被观察者&#xff0c;当被观察者状态发生改变时&#xff0c;它会通知所有的被观察者对象&#xff0c;使他们能够及时做出响应&#xff0c;所以也被称作“发布-订阅模式”。总得来说就是你关注了一个主播&#xff0c;主播的状态改变会通…

Rabbitmq发送邮件并消费邮件

&#x1f4d1;前言 本文主要是【Rabbitmq】——Rabbitmq发送邮件并消费邮件的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1…

小程序开发中SSL证书的重要作用

随着互联网技术的发展&#xff0c;越来越多的企业和个人开始开发自己的小程序来满足各种需求。然而&#xff0c;在这个过程中&#xff0c;安全性和稳定性成为了开发者必须关注的重点之一。为了保障用户的隐私安全和体验效果&#xff0c;越来越多的小程序开发者开始采用SSL证书进…

Sentaurus TCAD半导体器件入门常用案例合集

Sentaurus TCAD是用于模拟半导体器件和工艺的工具之一&#xff0c;可以帮助工程师设计电路元件&#xff0c;优化半导体工艺和器件性能。主要功能包括&#xff1a;半导体器件建模&#xff08;用于建立各种半导体器件的物理模型工艺模拟&#xff09;、半导体器件的制造工艺模拟&a…

VT-VRPA2-1-1X/V0/T5控制4WRE6比例方向阀放大板

带阀芯位移反馈不带集成式放大器比例方向阀控制放大器&#xff0c;替代力士乐同型号产品&#xff0c;可以完全互换使用&#xff1b;适用于控制力士乐系列带电位置反馈的4WRE6通径和4WRE10通径2X系列比例方向阀&#xff1b;0~10V、4~20mA指令控制信号任意可选&#xff1b;直接安…

电气制图用什么软件?CAD和Eplan哪个更胜一筹?

身为电气工程师&#xff0c;每天打交道最多的可能不是自家对象&#xff0c;而是时时刻刻攥在手里的电气图。目前市面上制作电路图的软件形形色色&#xff0c;但是AutoCAD Electrical和Eplan是目前大家使用率最高的两款电气制图软件。 EPLAN是一款专业的电气设计软件&#xff0…

GraphCast:基于机器学习的全球中期天气预测模型

文章信息 文章题为”GraphCast: Learning skillful medium-range global weather forecasting”&#xff0c;该文章于2023年发表至Science&#xff0c;文章内容主要关于利用机器学习模型&#xff0c;实现高效、准确的全球中期天气预测。由于文章内容较多&#xff0c;本文仅对研…

迷你洗衣机哪个牌子好又实惠?口碑最好的小型洗衣机

不得不说洗衣机的发明解放了我们的双手&#xff0c;而我们从小到大就有这个意识&#xff0c;贴身衣物不可以和普通的衣服一起丢进去洗衣机一起&#xff0c;而内衣裤上不仅有肉眼看见的污渍还有手上根本无法消灭的细菌&#xff0c;但是有一款专门可以将衣物上的细菌杀除的内衣洗…

MySQL进阶知识:一

目录 存储引擎 MySQL的体系结构 存储引擎简介 存储引擎特点 InnoDB 逻辑存储结构 MyISAM Memory 对比 存储引擎选择 索引 介绍 索引结构 BTree索引 Hash索引 索引分类 索引语法 SQL性能分析 SQL执行频率 慢查询日志 profile详情 explain执行计划 索引的…

SAP ABAP弹出对对话框错误信息设计

弹出对对话框错误信息设计、REUSE_ALV_POPUP_TO_SELECT 代码如下&#xff1a; IF lw_item_date-menge > lv_atp_other.lw_error-ebelp lw_item_date-ebelp.lw_error-matnr lw_item_date-matnr.lw_error-zlabst lv_labst.lw_error-zoccupy_so lv_occupy_s…

超实用电脑技巧分享,快速提高工作效率!

“我是个刚开始学习使用电脑的新手&#xff0c;想问问大家有什么比较好用的电脑使用技巧可以推荐一下吗&#xff1f;非常感谢&#xff01;” 在使用电脑时&#xff0c;如果我们适当掌握一些技巧&#xff0c;可以有效提高效率。那么&#xff0c;今天小编就给大家分享一些常见的电…

java 鸿鹄云商 SAAS云产品概述 saas商城 b2b2c商城 o2o商城 积分商城 秒杀商城 拼团商城 分销商城 短视频商城免费搭建

【SAAS云平台】打造全行业全渠道全场景的SaaS产品&#xff0c;为店铺经营场景提供一体化解决方案&#xff1b;门店经营区域化、网店经营一体化&#xff0c;本地化、全方位、一站式服务&#xff0c;为多门店提供统一运营解决方案&#xff1b;提供丰富多样的营销玩法覆盖所有经营…

rider编辑器抛出异常 忽略try catch

如题 代码加了try catch 后用户使用体验是好了 但开发过程中 报错了不方便排查 启用这些配置后 trycatch里的异常也会抛出 补充一下默认配置,方便还原

ICC2/innovus设置no 1x gap的方法

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 ICC2设置no 1x的方法如下: 1) set_placement_spacing_label -name X -lib_cells {*} -side right set_placement_spacing_label -name Y -lib_cells {*} -side left 2) set_placement_spacing_rul…

万人拼团团购小程序源码系统+拼团设置+拼团管理 附带完整的搭建教程

随着互联网的快速发展&#xff0c;电子商务和社交电商的兴起&#xff0c;团购作为一种高效的营销策略和消费方式&#xff0c;受到了广大消费者的热烈欢迎。在此背景下&#xff0c;我们开发了一款基于微信小程序的万人拼团团购系统&#xff0c;旨在为用户提供一种更加便捷、高效…

2023年的 Web 前端开发建议需要具备技能

2023年的 Web 前端开发需要具备一系列技能&#xff0c;以应对不断变化的技术环境和满足日益增长的业务需求。以下是一些可能被视为必备的技能&#xff0c;以及为什么这些技能在当今前端开发中显得至关重要&#xff1a; 一、JavaScript、HTML、CSS&#xff1a; 为什么重要&…

灰度发布专题---5、API网关灰度发布

API网关灰度发布 前面说到Dubbo灰度发布&#xff0c;那网关代理层如何实现灰度发布呢&#xff0c;在网关层实现灰度发布&#xff0c;我们可以采用2种方式实现&#xff0c;分别是权重和灰度规则配置。在这之前我们先了解下Gateway的源码&#xff0c;更利于后面灰度分析。 Gate…