详解贪心算法

news2024/9/21 12:32:46

贪心算法(Greedy Algorithm) 概述:

贪心算法是一种在求解最优化问题时采取的一种常用算法策略。贪心算法的基本思想是,每次选择当前情况下的局部最优解,并相信这个局部最优解能够导致全局最优解。贪心算法通过迭代的方式一步步地构建最优解,并不进行回溯。

贪心算法的一般步骤:

1. 将问题分解成多个子问题;
2. 对每个子问题,确定一个最优解;
3. 对每个子问题的最优解进行合并,得到原问题的最优解。


贪心算法的正确性需要满足两个条件:

1.最优子结构:问题的最优解能够由子问题的最优解组合而成。
2. 贪心选择性:通过局部最优选择能够得到全局最优解。


贪心算法适用的问题一般具有以下特点:

1. 子问题的最优解能够推导出原问题的最优解;
2. 子问题的最优解构成原问题的最优解时,原问题的最优解也能由它推导出。

贪心算法的优点是简单、高效,时间复杂度通常较低。然而,贪心算法并不适用于所有问题,有些问题需要使用其他更复杂的算法来求解。在使用贪心算法时,需要仔细分析问题的特点并证明贪心策略的正确性。


由于贪心是一种思想,没有具体的算法模板,而且贪心一般不会单独作为一种算法出现在题目中,一般会跟其他算法结合在一起出现。例如:动态规划、递归、高级数据结构等。在此基础上保证每一步时最优解的情况下就可以得到最优的答案。下面我们将以例题的形式让大家来了解这种思想。


例题一: 

AcWing 3769. 移动石子

题目:

一共有 n 个箱子排成一排,从左到右依次编号为 1∼n。

其中,第 i 号箱子中放有 ai个石子。

现在,你可以进行最多 d 次操作。

每次操作可以将一个石子从一个箱子移动至另一个与其相邻的箱子里。

我们希望通过合理操作使得 1 号箱子内的石子数量尽可能大。

请问,这个最大可能值是多少?

输入格式

第一行包含整数 T,表示共有 T 组测试数据。

每组数据第一行包含两个整数 n和 d。

第二行包含 n 个整数 a1,a2,…,an。

输出格式

每组数据输出一行结果,表示答案。

数据范围

1≤T≤100,
1≤n,d≤100,
0≤ai≤100.

输入样例:
3
4 5
1 0 3 2
2 2
100 1
1 8
0
输出样例:
3
101
0

解题思路:

这个题很明显贪心思想,要让第一个箱子尽可能多的石子,在操作次数的限制下,我们最优解,要从第二个箱子开始贪心,第二个、第三个...,这样可以使操作次数尽可能的少。

 


AC代码:
#include<iostream>
using namespace std;
const int N=105;
int t,n,d;
int a[N];
int main(){
	cin>>t;
	while(t--){
		cin>>n>>d;
		for(int i=1;i<=n;i++)cin>>a[i];
		int k=2;
		while(d){
			if(k>n)break;
			if(d>=a[k]*(k-1)){
				a[1]+=a[k];
				d-=a[k]*(k-1);
			}else{
				a[1]+=d/(k-1);
				d=0;
			}
			k++;
		}
		cout<<a[1]<<endl;
	}
	return 0;
}

例题二:

洛谷 P1007 独木桥

题目背景

战争已经进入到紧要时间。你是运输小队长,正在率领运输部队向前线运送物资。运输任务像做题一样的无聊。你希望找些刺激,于是命令你的士兵们到前方的一座独木桥上欣赏风景,而你留在桥下欣赏士兵们。士兵们十分愤怒,因为这座独木桥十分狭窄,只能容纳 1 个人通过。假如有 2 个人相向而行在桥上相遇,那么他们 2 个人将无法绕过对方,只能有 1 个人回头下桥,让另一个人先通过。但是,可以有多个人同时呆在同一个位置。

题目描述

突然,你收到从指挥部发来的信息,敌军的轰炸机正朝着你所在的独木桥飞来!为了安全,你的部队必须撤下独木桥。独木桥的长度为 L,士兵们只能呆在坐标为整数的地方。所有士兵的速度都为 1,但一个士兵某一时刻来到了坐标为 0 或 L+1 的位置,他就离开了独木桥。

每个士兵都有一个初始面对的方向,他们会以匀速朝着这个方向行走,中途不会自己改变方向。但是,如果两个士兵面对面相遇,他们无法彼此通过对方,于是就分别转身,继续行走。转身不需要任何的时间。

由于先前的愤怒,你已不能控制你的士兵。甚至,你连每个士兵初始面对的方向都不知道。因此,你想要知道你的部队最少需要多少时间就可能全部撤离独木桥。另外,总部也在安排阻拦敌人的进攻,因此你还需要知道你的部队最多需要多少时间才能全部撤离独木桥。

输入格式

第一行共一个整数 L,表示独木桥的长度。桥上的坐标为 1,2,⋯ L。

第二行共一个整数 N,表示初始时留在桥上的士兵数目。

第三行共有 N 个整数,分别表示每个士兵的初始坐标。

输出格式

共一行,输出 2 个整数,分别表示部队撤离独木桥的最小时间和最大时间。2 个整数由一个空格符分开。


解题思路:

这个题看似显得很累赘,但是做过此类型题的一眼就能看穿,在《挑战程序设计竞赛》这本书上就有详细的解释,当然它们是蚂蚁过桥为背景。解这题的关键在于最大值的求解,我们知道最小值就是在独木桥两边的士兵直接往两端走就可以,走左边还是右边min一下,因为要求所有部队通过所以在所有值里面去一个最大值。对于最大时间的求解,那么我就让靠近左边的人往右边走,靠经右边的人往左边走,如果两个人碰头时,它们可以交换灵魂继续前进,这是《挑战程序设计竞赛》上思想,意思就是我变成他继续前进,他变成我继续前进,最后是对结果没有影响的。那么最大时间就是在最大值里面取一个最大值。

综上所述,最小时间是最小值里面的最大值,最大时间是最大值里面的最大值。


AC代码:
#include<iostream>
#include<algorithm>
using namespace std;
const int N=5e3+5;
int n,l,x;
int a[N];
int main(){
	cin>>l>>n;
	for(int i=0;i<n;i++){
		cin>>a[i];
	}
	sort(a,a+n);//先排序
	int minx=0;
	int maxx=0;
	for(int i=0;i<n;i++){
		minx=max(min(a[i],l+1-a[i]),minx);//最小时间
		maxx=max(maxx,max(a[i],l+1-a[i]));//最大时间
	}
	cout<<minx<<" "<<maxx<<endl;
	return 0;
}

例题三: 

AcWing 507. 积木大赛

题目:

春春幼儿园举办了一年一度的“积木大赛”。

今年比赛的内容是搭建一座宽度为 n 的大厦,大厦可以看成由 n 块宽度为 1 的积木组成,第 i 块积木的最终高度需要是 hi。

在搭建开始之前,没有任何积木(可以看成块高度为 0 的积木)。

接下来每次操作,小朋友们可以选择一段连续区间 [L,R],然后将第 L 块到第 R 块之间(含第 L 块和第 R 块)所有积木的高度分别增加 1。

小 M 是个聪明的小朋友,她很快想出了建造大厦的最佳策略,使得建造所需的操作次数最少。

但她不是一个勤于动手的孩子,所以想请你帮忙实现这个策略,并求出最少的操作次数

输入格式

输入包含两行,第一行包含一个整数 n,表示大厦的宽度。 

第二行包含 n 个整数,第 i 个整数为 hi。

输出格式

仅一行,即建造所需的最少操作数。

数据范围

1≤n≤105,
0≤hi≤10000

输入样例:
5
2 3 4 1 2
输出样例:
5

解题思路:

这可不是一道纯正的贪心,因为读完题就知道是差分了,但是为什么还要归到贪心里面,因为贪心是一种思想,上面三个题目都涉及到了最大、最小,一般这种就有贪心思想了,当然,这一个题,会了差分就迎刃而解了,具体的贪心还是体现在算法操作上,比如这个题中间的数最大,那么每次选择区间加一都尽量选上这个数,这样可以使操作次数最小。


AC代码:
#include<iostream>
using namespace std;
int n,ans;
const int N=1e5+5;
int h[N];
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>h[i];
	}
	for(int i=n+1;i>=1;i--){
		h[i]=h[i]-h[i-1];//差分数组
	}
	for(int i=1;i<=n+1;i++){
		if(h[i]>0){
			ans+=h[i];
		}
	}
	cout<<ans<<endl;
	return 0;
}

其他例题:

第十四届蓝桥杯省赛大学C组(C/C++)三国游戏_c语言三国游戏-CSDN博客

AcWing 4262. 空调(每日一题)-CSDN博客

AcWing 1262. 鱼塘钓鱼(每日一题)-CSDN博客

AcWing 505. 火柴排队(每日一题)-CSDN博客


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

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

相关文章

Linux学习第57天:Linux PWM驱动实验

Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 本章的思维导图如下&#xff1a; 一、PWM驱动简析 1、设备树下的PWM控制节点 8 路 PWM 都属于 I.MX6ULL 的 AIPS-1 域&#xff0c;分为了两部分&#xff0c; PWM1~P…

Spring Boot 中使用 JSON Schema 来校验复杂JSON数据

JSON是我们编写API时候用于数据传递的常用格式&#xff0c;那么你是否知道JSON Schema呢&#xff1f; 在数据交换领域&#xff0c;JSON Schema 以其强大的标准化能力&#xff0c;为定义和规范 JSON 数据的结构与规则提供了有力支持。通过一系列精心设计的关键字&#xff0c;JS…

MySQL的安装数据库的简单操作

&#x1f48e;所属专栏&#xff1a; MySQL &#x1f48e;1. 数据库相关概念 数据库&#xff1a;存储数据的仓库&#xff0c;数据是有组织的进行存储 数据库管理系统&#xff1a;操纵和管理数据库的大型软件 SQL:操作关系型数据库的编程语言&#xff0c;定义了一套操作关系型…

基于Session和Cookie的模拟登录实战

准备工作 安装好 requests 库&#xff0c; 并掌握基本用法 安装 Selenium 库&#xff0c; 并掌握基本用法 案例介绍 用到的网站&#xff1a; https://login2.scrape.center/ 用户名和密码&#xff1a; admin 点击登录 这个网站是基于传统的 MVC 模式开发的&#xff0c;比较…

DM 数据迁移工具

1.1.概述 DM 数据迁移工具 DM DTS 提供了主流大型数据库迁移到 DM、DM 到 DM、文件迁移到 DM 以及 DM 迁移到文件等功能。 得益于 DM 数据库对目前主流大型关系型数据库系统有着业界领先的兼容性&#xff0c;在存储层面、语法层面、接口层面和它们保持高度兼容&#xff0c;借…

为什么企业需要进行能源体系认证?

通过能源体系认证&#xff0c;企业可以向公众和利益相关方展示其在节能减排方面的承诺和成就。这不仅提升了企业的社会责任形象&#xff0c;还增强了品牌的信誉度。在当今消费者更加关注环境问题的背景下&#xff0c;绿色企业形象有助于赢得市场和客户的认可与信任。 能源体系认…

江协科技51单片机学习- p33 PWM呼吸灯和直流驱动电机调速

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

《python语言程序设计》2018版第6章第34题正多边形的面积 重写3.5题返回正多边形的面积

def area(n, side):n eval(input("Enter the number of sides: ")) # 多边形的边数side eval(input("Enter the side: ")) # 多边形的长度area_num (n * pow(side, 2)) / (4 * math.tan(math.pi / n))print("The area of the pentagon is {:>…

t-分布随机邻域嵌入和多维尺度分析

t-分布随机邻域嵌入 (t-Distributed Stochastic Neighbor Embedding, t-SNE) t-SNE 是一种非线性降维方法&#xff0c;主要用于高维数据的可视化。它能够将高维数据映射到低维空间&#xff0c;同时保留数据的局部结构。 原理 t-SNE 通过将高维空间中的相似度分布与低维空间中…

KVM——安装桌面版本Rocky_linux9.4

安装桌面版本Rocky_linux9.4 一些配置见图

超级会员卡积分商城小程序多功能源码系统 带完整的安装代码包以及部署教程

源码系统概述 超级会员卡积分商城小程序多功能源码系统是一款集合了多种功能于一体的会员积分商城小程序源码系统。该系统采用先进的技术架构&#xff0c;支持多门店统一管理&#xff0c;提供丰富的会员信息和商品管理服务&#xff0c;支持多种支付方式和营销活动&#xff0c;同…

【css】3d柱状图-vue组件版

创建一个响应式圆柱形进度条组件 在现代网页设计中&#xff0c;圆柱形进度条是一种非常流行的视觉元素&#xff0c;用于展示数据的进度或状态。本文将介绍如何使用Vue.js和LESS创建一个响应式的圆柱形进度条组件。 组件结构 我们的组件由两部分组成&#xff1a;一个圆柱形的…

【密码学】聚合签名

聚合签名是一种高级的数字签名技术&#xff0c;这种技术在多种场景下都非常有用&#xff0c;特别是在区块链、多方计算、分布式系统等领域中。下面让我来对它的基本概念、主要类型、实现步骤等来进行介绍。 一、聚合签名的基本概念 聚合签名到底是什么&#xff1f;有那么多数字…

四个开源的模拟人类记忆开源库

✨ 1: Memary Memary 是一个模拟人类记忆、增强AI代理的开源Python库。 Memary 是一个模拟人类记忆来提升人工智能代理性能的工具。其核心是通过集成多个模型&#xff08;如本地运行的 Llama 和 GPT 模型&#xff09;以及使用知识图谱、记忆流和实体知识存储来推进 AI 代理的…

前端(HTML + CSS)学成在线项目(仿)

头部区域 banner区域 精品推荐区域&#xff0c;这三个区域都是版心居中 头部区域分为&#xff1a;logo 导航 搜索 用户四个小块 鼠标悬停 :hover效果 banner区域分为&#xff1a;左侧导航 背景图 右侧课程表 鼠标悬停 :hover效果 精品推荐区域 鼠标悬停 :hover效果 精…

基于MATLAB车牌图像识别的设计与实现

摘 要 车牌图像识别系统是现代智能交通管理的重要组成部分之一。车牌识别系统使车辆管理更智能化&#xff0c;数字化&#xff0c;有效提升了交通管理的方便性和有效性。 车牌识别系统主要包括了图像采集、图像预处理、车牌定位、字符分割、字符识别等五大核心部分。本文主要介绍…

顺序表-数据结构

一、结构定义 顺序表是通常是数组&#xff0c;要求数据连续存储。顺序表又分为定长顺序表和变长顺序表&#xff0c;本文实现后者。 1、头文件 #include <stdio.h> #include <stdlib.h> 2、定长顺序表 #define MAX 100 定长顺序表结构 typedef struct SqList {…

五种创建springBoot项目的方法(本质上是三种)

文章目录 1. 使用https://start.aliyun.com/的服务器URL2. 使用https://start.spring.io/3. https://start.spring.io/使用官网4. 使用https://start.aliyun.com/5. 使用maven构建springboot项目5.1 点击maven&#xff0c;什么也不选&#xff0c;点击下一步5.2 修改名称和组ID&…

c语言第十天笔记

函数的概述 函数&#xff1a; 实现一定功能的&#xff0c;独立的代码模块。我们的函数一定是先定义&#xff0c;后使用。 使用函数的优势&#xff1a; 1. 我们可以通过函数提供功能给别人使用。当然我们也可以使用别人提供的函数&#xff0c;减少代码量。 2. 借助函数可以…

《学会 SpringMVC 系列 · 参数解析器 ArgumentResolvers》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…