贪心算法总结

贪心的定义(摘自百度百科)

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

贪心算法是以局部最优而达到全局最优,可以说贪心算法是短视的,每次只考虑当前状况下最好的选择。 

贪心并没有通用的模板和算法思路,大多时候是靠刷题积累。


区间问题

AcWing 905. 区间选点

思路分析: 

        1. 按照右端点从小到大将区间排序

        2. 依次从前往后枚举每个区间:

                1 > 若当前区间能覆盖所选点,无需操作

                2 > 若当前区间不能覆盖所选点,就选择当前区间的右端点作为新选的点,

                     同时答案要加一

代码展示:
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010;
struct Edge
{
    int l, r;
    bool operator < (const Edge &W)const
    {
        return r < W.r;
    }
}edges[N];
int main()
{
    int n;
    cin >> n;
    
    for (int i = 0; i < n; i ++)
    {
        int l, r;
        cin >> l >> r;
        edges[i] = {l, r};
    }
    sort(edges, edges + n);
    int res = 0, ed = -2e9;
    for (int i = 0; i < n; i ++)
    {
        if (edges[i].l > ed)
        {
            res ++;
            ed = edges[i].r;
        }
    }
    cout << res << endl;
    return 0;
}

AcWing 908. 最大不相交区间数量

代码展示:
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010;
struct Edge
{
    int l, r;
    bool operator <(const Edge &W)const
    {
        return r < W.r;
    }
}edges[N];

int main()
{
    int n;
    cin >> n;
    
    for (int i = 0; i < n; i ++)
    {
        int l, r;
        cin >> l >> r;
        edges[i] = {l, r};
    }
    
    sort(edges, edges + n);
    
    int res = 0, ed = -2e9;
    for (int i = 0; i < n; i ++)
    {
        if (edges[i].l > ed)
        {
            res ++;
            ed = edges[i].r;
        }
    }
    
    cout << res << endl;
    return 0;
}

 AcWing 906. 区间分组  

思路分析:

        1. 区间按照左端点从小到大排序

        2. 用小根堆去存储每组的右端点的最大值

        3. 从前往后处理每一个区间:

                1 > 若当前区间的左端点小于堆顶,说明当前区间与前面所有组都存在交集,

                        那么就开一个新的组去存储当前区间

                2 > 若当前区间的左端点大于堆顶,说明当前区间和堆顶无交集,

                      则可以将当前区间添加到堆顶所在组中,

                      即要更新该组在小根堆中存储的右端点数值

代码展示: 
#include <iostream>
#include <algorithm>
#include <queue>

using namespace std;

const int N = 100010;
//按照区间左端点大小排序
struct Range
{
    int l, r;
    bool operator <(const Range &W)const
    {
        return l < W.l;
    }
}edges[N];

int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i ++)
    {
        int l, r;
        cin >> l >> r;
        edges[i] = {l, r};
    }
    
    sort(edges, edges + n);
    priority_queue<int, vector<int>, greater<int>> heap;
    
    for (int i = 0; i < n; i ++)
    {
        //当前枚举的区间
        auto t = edges[i];
        //当堆中为空或者与堆顶元素有交集
        if (heap.empty() || heap.top() >= t.l) heap.push(t.r);
        else
        {
            heap.pop();
            heap.push(t.r);
        }
    }
    
    cout << heap.size() << endl;
    return 0;
}

AcWing 907. 区间覆盖

思路分析:

        1. 区间按照左端点从小到大排序

        2. 从前往后枚举每个区间(双指针算法)

                每次选取能覆盖当前点st并且右端点最大的区间,然后更新st

代码展示:
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010;

struct Edge
{
    int l, r;
    bool operator <(const Edge &W)const
    {
        return l < W.l;
    }
}edges[N];

int main()
{
    int st, ed;
    cin >> st >> ed;
    int n;
    cin >> n;
    for (int i = 0; i < n; i ++)
    {
        int l, r;
        cin >> l >> r;
        edges[i] = {l, r};
    }
    sort(edges, edges + n);
    
    int res = 0;
    bool flag = false;
    //找到能覆盖当前点的最靠右的区间,更新当前点
    for (int i = 0; i < n; i ++)
    {
        int j = i, r = -2e9;
        while (j < n && st >= edges[j].l) 
        {
            r = max(r, edges[j].r);
            j ++;
        }
        
        if (r < st) 
        {
            res = -1;
            break;
        }
        res ++;
        if (r >= ed) 
        {
            flag = true;
            break;
        }
        
        st = r;
        i = j - 1;
    }
    
    if (!flag) res = -1;
    cout << res << endl;
    return 0;
}

 Huffman树

哈夫曼树定义(摘自百度百科)

给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。

哈夫曼树的构造 

每次选取最小的两个数作为两个权值相加的节点的子节点,在将该节点与未选取的值再重复操作

以一个样例来模拟这个过程:

AcWing 148. 合并果子

 思路分析:

        用小根堆来存储权值,然后构造以哈夫曼树的思路得出最终结果

代码展示:
#include <iostream>
#include <algorithm>
#include <queue>

using namespace std;

priority_queue<int, vector<int>, greater<int>> heap;

int main()
{
    int n;
    cin >> n;
    while (n --)
    {
        int x;
        cin >> x;
        heap.push(x);
    }
    
    int res = 0;
    
    while (heap.size() > 1)
    {
        int a = heap.top();
        heap.pop();
        int b = heap.top();
        heap.pop();
        res += (a + b);
        heap.push(a + b);
    }
    
    cout << res << endl;
    return 0;
}

排序不等式

AcWing 913. 排队打水

代码展示: 

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010;
typedef long long LL;

int a[N];

int main()
{
    int n;
    cin >> n;
    
    for (int i = 0; i < n; i ++) cin >> a[i];
    
    sort(a, a + n);
    
    LL res = 0;
    for (int i = 0; i < n; i ++)
        res += a[i] * (n - i - 1);
        
    cout << res << endl;
    return 0;
}

绝对值不等式

公式:

        | |a| - |b| | ≤ | a±b | ≤ |a| + |b|

 AcWing 104. 货仓选址

代码展示:

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010;

int a[N];

int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i ++) cin >> a[i];
    
    sort(a, a + n);
    
    int res = 0;
    
    for (int i = 0; i < n; i ++)
        res += a[i] - a[i / 2];
 
    
    cout << res << endl;
    return 0;
}


推公式

AcWing 125. 耍杂技的牛

代码展示:

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010;
typedef pair<int, int> PII;

PII cow[N];

int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i ++)
    {
        int w, s;
        cin >> w >> s;
        cow[i] = {w + s, w};
    }
    
    sort(cow, cow + n);
    
    int res = -2e9, sum = 0;
    for (int i = 0; i < n; i ++)
    {
        int w = cow[i].second, s = cow[i].first - w;
        res = max(res, sum - s);
        sum += w;
    }
    
    cout << res << endl;
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

EasyRecovery易恢复16中文免费版下载

最近一直在加班码方案&#xff0c;抓bug&#xff0c;熬夜都成了家常便饭。原本以为这种艰难的生活快要迎来胜利的曙光&#xff0c;偏偏老天还要给我再来当头一棒&#xff01;写完方案被我误删了&#xff0c;而且还彻底清空了废纸篓&#xff0c;团队几天几夜的成果毁于一旦&…

[极客大挑战 2019]Secret File 1

题目环境&#xff1a; 网页什么都没有&#xff0c;GET那里也没有任何参数和文件 F12查看隐藏文件发现隐藏文件点进去看看发现一个可点击按钮SECRET 好家伙&#xff0c;什么都没有 这里猜测还有隐藏文件目录扫描使用工具dirsearch命令&#xff1a;python dirsearch.py -u [http:…

微服务-Feign

文章目录 Feign介绍Feign的基本使用自定义Feign的配置Feign性能优化Feign最佳实践 Feign介绍 RestTemplate远程调用存在的问题&#xff1a;代码可读性差&#xff0c;java代码中夹杂url&#xff1b;参数复杂很难维护 String url "http://userservice/user/" order.g…

纬创出售印度子公司给塔塔集团,结束iPhone代工业务 | 百能云芯

纬创&#xff08;Wistron&#xff09;董事会于10月27日通过决议&#xff0c;同意以1.25亿美元的价格出售其印度子公司Wistron InfoComm Manufacturing (India) Private Limited&#xff08;WMMI&#xff09;的100%股权给塔塔集团&#xff0c;交割将尽快完成。此举将意味着纬创退…

3ds Max2022安装教程(最新最详细)

目录 一.简介 二.安装步骤 网盘资源见文末 一.简介 3DS Max是由Autodesk公司开发的一款专业三维建模、动画和渲染软件&#xff0c;广泛应用于影视、游戏、建筑和工业设计等领域。 3DS Max的主要特点和功能包括&#xff1a; 三维建模&#xff1a;3DS Max提供了各种强大的建…

【Python 零基础入门】Numpy 常用函数

【Python 零基础入门】内容补充 3 Numpy 常用函数 概述Numpy 数组创建np.arangenp.linspace 数组操作reshapeflattenconcatenatesplitvstackhstack 数学运算add 相加subtract 相减multiply 相乘divide 相除 通用函数np.sqrt 平方根np.log 对数np.exp 指数np.sin 正弦 概述 Num…

如何有效使用蜂邮EDM和vba批量发送邮件?

蜂邮EDM和vba批量发送邮件的方法&#xff1f;怎么使用蜂邮EDM和vba代码群发电子邮件&#xff1f; 批量发送邮件已经成为一种不可或缺的沟通方式。蜂邮EDM和VBA是两个功能强大的工具&#xff0c;可以帮助您在邮件营销和业务通信中实现高效的批量发送邮件操作。接下来将介绍如何…

Java设置日期时间的毫秒数为0

背景 做一个发送短信的需求&#xff0c;采用RabbitMQ来实现定时发送。发送时需要验证发送短信任务的预计发送时间和生产者传过来的时间是否一致&#xff0c;一致才发送。 结果在调试的时候&#xff0c;却发现任务一直没法触发。一步步调试&#xff0c;发现是两个时间不相等。明…

理解springboot那些过滤器与调用链、包装或封装、设计模式相关等命名规范,就可以读懂80%的springboot源代码,和其他Java框架代码

紧接上面《 理解springboot那些注册与回调、监控与统计等命名规范,就可以读懂70%的springboot源代码》、《 理解springboot那些约定俗成的框架类名、全局context等命名规范,就可以读懂一半springboot的源代码》2篇文章,此片将汇总springboot那些过滤器与调用链、包装或封装…

【C++ 系列文章 -- 程序员考试 201811 下午场 C++ 专题 】

1.1 C 题目六 阅读下列说明和C代码&#xff0c;填写程序中的空&#xff08;1&#xff09; &#xff5e;&#xff08;5&#xff09;&#xff0c;将解答写入答题纸的对应栏内。 【说明】 以下C代码实现一个简单乐器系统&#xff0c;音乐类&#xff08;Music&#xff09;可以使用…

防雷接地测试方法完整方案

防雷接地是保障电力系统、电子设备和建筑物安全的重要措施&#xff0c;防雷接地测试是检验防雷接地装置是否合格的必要手段。本文介绍了防雷接地测试的原理、方法和注意事项&#xff0c;以及如何编写防雷接地测试报告。 地凯科技防雷接地测试的原理 防雷接地测试的基本原理是…

驱动开发11 编写iic驱动-读取温湿度数据

头文件 head.h #ifndef __HEAD_H__ #define __HEAD_H__ #define GET_HUM _IOR(m, 1, int) #define GET_TEM _IOR(m, 0, int) #endif 应用程序 si7006.c #include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #inc…

高效学习工具之AnkiMobile新手入门指南(ios端,包括ipad、ihpone设备)————创建、使用、备份、设置参数、相关资料

文章目录 0 背景0.1 闭环学习0.2 什么是anki0.3 anki践行者经验分享 1 开始使用1.1 导入1.2 创建空白组1.3 创建卡片1.3.1 利用anki创建卡片的两种方法1.3.2 复习材料分类 1.4 筛选&#xff08;做减法&#xff0c;拆分学习&#xff08;做子卡牌集合&#xff09;&#xff09;&am…

4.1 继承

思维导图&#xff1a; 第4章 面向对象(下) 学习目标: 了解面向对象中的继承特性&#xff0c;掌握继承的概念与特点。掌握方法的重写&#xff0c;能够在子类中重写父类方法。掌握super关键字&#xff0c;明白如何在类中使用super访问父类成员。理解final关键字的作用&#xff0…

微信小程序如何使用地球半径计算两组经纬度点之间的距离(自身位置与接口返回位置)【上】

目录 1.配置位置权限 2.获取当前自身经纬度 3. 请求接口拿到返回经纬 4. 循环取每一项的经纬 5.如何判断是否打开了定位权限 6.进行距离计算操作 7.运行效果 8.完整代码 首先在使用小程序时&#xff0c;请求的接口一定要去配置合法域名&#xff0c;才能够进行接下来…

缓存击穿只会逻辑过期 OR 互斥锁?深入思考 == 鹤立鸡群

网上但凡看得见的文章&#xff0c;大部分在说缓存穿透时都是无脑分布式锁 / 逻辑过期&#xff0c;分布式锁一点问题都没有么&#xff1f;逻辑过期一点问题都没有么&#xff1f;还能不能再进一步优化&#xff1f; 在聊聊缓存击穿的双重判定锁之前&#xff0c;我们将按照循循渐进…

双十一首日捷报 | 德施曼率先破亿,再度蝉联智能锁品类第一

10月31日晚8:00&#xff0c;各大平台迎来了双十一第一波现货开售。其中&#xff0c;在智能锁类目中德施曼势头最为迅猛&#xff0c;此前&#xff0c;德施曼凭借“全民换锁季”主题活动&#xff0c;在预售期间就已经全面引爆消费者换锁热潮&#xff0c;随着此次现货开售&#xf…

cut 命令

cut [选项参数] filename #默认分隔符是制表符 选项参数&#xff1a; -d delimiter 分隔符 -f field 场地、领域&#xff08;第几列&#xff09; 命令使用&#xff1a; cut -d " " -f 1 cut.txt #空格为分隔符截取第1列cut -d " " -f 2,3 cut.txt #截…

百度上传自己个人简介攻略,个人介绍百度百科怎么做?

个人介绍要展示在百度百科上该怎么操作&#xff0c;我们都清楚百度百科词条是需要申请才能拥有的&#xff0c;但是没有百度上传自己个人简介的攻略&#xff0c;很多人是不知从何下手的。下面洛希爱做百科网带着大家一起来了解。 一、了解百度百科词条的创建规则 1. 词条名称规…

jdk官网下载(详细步骤)

jdk全部版本下载网址 Java Archive | Oraclehttps://www.oracle.com/java/technologies/downloads/archive/ 下载之前先建立oracle账号(免费创建)&#xff0c;不用特意去搜&#xff0c;你点击下载jdk的时候会自动弹出来&#xff0c;自己建立一个账号就能下载了 找到自己要下载…