NOIP实用算法 4.贪心方法

NOIP复习篇———贪心 阅读详情

4.贪心方法
a.工程计划模型
b.部分背包与每步最优
c.构造贪心算法

a.工程计划模型

我们常常碰到这样的问题:完成一个工程需要若干个步骤,每个步骤都有若干种方法,图示——

步骤a  步骤b  步骤c  ... 步骤n
       方法b1 方法c1
方法a1 方法b2 方法c2     方法n1
方法a2 方法b3 方法c3
              方法c4

每个方法有一个权值(如效率、质量),其大小往往和其他步骤中选取的方法有关。有些时候权值无意义,表示方法不可选择。要求给出一个方法组合,是权值和最大。
在这里,暂且把它称作“工程计划”。很多实际问题都可以归纳为这个模型。
对于不同形式的工程计划,我们有不同的解法。
若权值与整个过程或前后步骤的方法选择都有关,我们使用搜索算法——时间复杂度高得吓人。
若每个权值只与上(或下)一步或少数几步的方法选择都有关,我们使用动态规划——有比较高的效率,在下一章会讲到。
若每个权值与其他步骤的方法选择都没有关系,我们使用贪心方法。


b.部分背包与每步最优

强调:每个权值与其他步骤的方法选择都没有关系。这样每步最优就可以得到全局最优——每一步都取最大的权值就可以了。
换而言之,贪心算法要求,局部的贪心选择,可以组成全局的最优解。
在实际问题中,这是需要证明的。如果这个无法证明,贪心算法所得的解不是最优解,一般只是较优解(较优解可为搜索剪枝提供方便)。

下面是贪心算法最经典的例子:部分背包问题。(下一章会讲到另外两种背包问题。)
问题:有N件物品和一个最大载重为M的背包,每件物品都有相应的重量和价值。现要求给出一个存放方案,使背包中物品总价值最大。部分背包要求,每件物品都可只装入它的一部分(部分重量有成比例的部分价值)。所涉及到的数字均为整数。
(注:有时该问题表述为体积形式,即背包体积有限,每件物品有体积和价值。在本系列我选择表述为重量形式。)
思路:背包中物品总价值最高,即单位重量物品价值最高。显然,应该多装单位重量价值高的物品。这样,我们先装入单位重量价值最高的物品,再装入第二高的……直到重量达到M(有必要时最后一件物品只装一部分),已达到物品总价值最高。
这个证明应该很严谨吧~
该算法时间复杂度O(n),效率很高;而且实现很容易。这些是贪心法最大的特点。

很多竞赛题看似可以用贪心法,其实贪心法得不到最优解,原因是每一步的选择对其他步骤有影响。
数字三角形问题:有一个数字三角形(如下图)。现有一只蚂蚁从顶层开始向下走,每走下一级时,可向左下方向或右下方向走。求走到底层后它所经过的数的最大值。

    1
   6 3
  8 2 6
 2 1 6 5
3 2 4 7 6

如果用贪心法,每次向最大的方向走,得到结果为1+6+8+2+3=20。可是明明还有另一条路,1+3+6+6+7=23。
问题出在哪?每次的选择对后面的步骤会有影响!第三级选了8,就选不到第四、五级较大的数了。
这个问题正确的解法会在下一章介绍。
有一个很实用的小技巧:竞赛题会给出数据规模。通过数据规模,我们可以大致判断该用何种算法。贪心算法可承受的数据规模很大,一般都会上万。如果给出的数据规模是100或1000,优先考虑动态规划吧。

c.构造贪心算法

构造与证明是贪心算法的难点,常常要求我们要有敏锐的观察力、多角度思考的变通能力、丰富的数学知识和推理能力。
下面举几个贪心算法的例子,供大家揣摩、掌握规律。

删数问题:给出一个N位的十进制高精度数,要求从中删掉S个数字(其余数字相对位置不得改变),使剩余数字组成的数最小。
算法构造:
1.每次找出最靠前的这样的一对数字——两个数字紧邻,且前面的数字大于后面的。删除这对数字中靠前的一个。
2.重复步骤1,直至删去了S个数字或找不到这样的一对数。
3.若还未删够S个数字,则舍弃末尾的部分数字,取前N-S个。
证明思路:显然,在只删一个数字时,唯有步骤1的方法能使数变小;可推理得出,删多个数字时,所有最优的方法都可看做是对步骤1的重复。也就是说,以上方法是最优策略之一。
在文末的附件中给出了这个算法的源代码。

工序问题:n件物品,每件需依次在A、B机床上加工。已知第i件在A、B所需加工时间分别为A[i]、B[i],设计一加工顺序,使所需加工总时间最短。
算法构造:
1.设置集合F、M、S:先加工F中的,再加工M中的,最后加工S中的。
2.对第i件,若A[i]>B[i],则归入S;若A[i]=B[i],则归入M。
3.对F中的元素按A[i]升序排列,S中的按B[i]降序排列。
证明思路:
1.F中的能“拉开”A、B加工同一件工件的结束时刻,为后面的工件加工“拉开时间差”,利于节省总时间。S中的刚好相反。因而,F中元素放在最前一定是最优策略之一。
2.F中A[i]小的前置,可以缩短开始时B的空闲时间,但会使F所有工件“拉开的时间差”缩短。不过可以证明,后者带来的损失不大于前者获得的优势。对称地,对S也一样。因而步骤3是可行的。

种树问题:一条街道分为n个区域(按1-n编号),每个都可种一棵树。有m户居民,每户会要求在区域i-j区间内种至少一棵树。现求一个能满足所有要求且种树最少的方案。
算法构造:
1.对于要求,以区间右端(升序)为首要关键字,左端(升序)为次要关键字排序。
2.按排好的序依次考察这些要求,若未满足,则在其最右端的区域种树,这时可能会满足多个要求。
证明思路:解法并不唯一,关键是证明没有比该解法更好的解法。按步骤1排序之后,会发现对于每个要求,在最右边的区域内种树所得的结果总不会差于在其他区域种树。至于为什么这样排序,留给你——读者们思考吧。
在文末的附件中给出了这个算法的源代码。


//删数问题 
//This C source file for program "Delete Number" is written by LastLeaf
//blog.programet.cn
//Edit 3

#include "stdio.h"

#define N_MAX 100
#define S_MAX 90
#define L_MAX (N_MAX-S_MAX)

int In[N_MAX+1],Out[N_MAX];

void cal(int *stIn,int lenIn,int *stOut,int lenOut)
{
	int iIn=0,iOut=0,dc;
	
	dc=lenIn-lenOut;
	
	for(;iIn<lenIn;)
		if(stIn[iIn]>stIn[iIn+1] && dc)
		{
			if(iOut>0)stIn[iIn]=stOut[--iOut];
			else iIn++;
			dc--;
		}
		else
			stOut[iOut++]=stIn[iIn++];
	
	return;
}

int main()
{
	int i,N,S;
	char c;
	FILE *fp;

	fp=fopen("DeleteNumber.in","r");
	fscanf(fp,"%d %d\n",&N,&S);
	for(i=0;i<N;i++)
	{
		fscanf(fp,"%c",&c);
		In[i]=c-'0';
	}
	In[i]=10;
	fclose(fp);
	
	cal(In,N,Out,N-S);

	fp=fopen("DeleteNumber.out","w");
	for(i=0;i<N-S;i++)
	{
		fprintf(fp,"%d",Out[i]);
	}
	fprintf(fp,"\n");
	fclose(fp);

    return 0;
}

//种树问题
//一条街道分为n个区域(按1-n编号),每个都可种一棵树。有m户居民,每户会要求在区域i-j区间内种至少一棵树。现求一个能满足所有要求且种树最少的方案。
//written by LastLeaf
//blog.programet.cn

#include <stdio.h> 
int main()
{
	FILE *fp;
	int N,H,B[5001],E[5001],T[5001],i,ii,m,n,P[30001],total=0,right,down;
	
	fp=fopen("trees.in","r");
	fscanf(fp,"%d\n%d\n",&N,&H);
	for(i=0;i<H;i++)
	{
		fscanf(fp,"%d %d %d",&B[i+1],&E[i+1],&T[i+1]);
		for(ii=0;ii<i;ii++)if(B[i+1]<=B[ii])break;
		for(;B[i+1]==B[ii];ii++)if(E[i+1]<E[ii])break;
		if(ii!=i)
			for(m=i;m>ii;m--)
			{
				B[m]=B[m-1];
				E[m]=E[m-1];
				T[m]=T[m-1];
			}
		B[ii]=B[i+1];
		E[ii]=E[i+1];
		T[ii]=T[i+1];
	}
	close(fp);
	
	for(i=0;i<=N;i++)P[i]=0;//初始化 
	for(i=0;i<H;i++)
	{
		while(T[i]>0)
		{
			right=E[i];
			//选择位置
			for(down=i+1;B[down]<=right && down<H;down++)
				if(E[down]<right)right=E[down];
			for(;P[right]==1;right--);
			//种树
			total++;
			P[right]=1;
			for(ii=i;ii<down;ii++)
			{
				if(right>=B[ii])
				{
					T[ii]--;
					if(T[ii]==0)
					{
						B[ii]=-1;
						E[ii]=N+1;
					}
				}
			} 
		}
	}
	
	fp=fopen("trees.out","w");
	fprintf(fp,"%d\n",total);
	for(i=1;i<=N;i++)
		if(P[i]==1)fprintf(fp,"%d ",i);
	fprintf(fp,"\n");
	fclose(fp);
	return 0;
}




http://blog.programet.org/2009/07/noip%E5%AE%9E%E7%94%A8%E7%AE%97%E6%B3%95-4-%E8%B4%AA%E5%BF%83%E6%96%B9%E6%B3%95.html#comment-11144

【C++-NOIP篇-4】 [NOIP2007 普及组] 纪念品分组 如果最大的a[r]不与最小的a[l]分在一组,而是a[r]与a[i]在一组,a[l]与a[j]在一组,因为a[l]=a[j],所以交换两者分组不影响后续选择,而a[r]如果不能与a[l]在一组,因为a[l]为当前最小值,所以a[r]只能单独为一组,所以贪心是 正确的。为使得参加晚会的同学所获得 的纪念品价值相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品, 并且每组纪念品的价格之和不能超过一个给定的整数。NOIP2007 普及组 T2。 阅读详情

相关推荐

从均分纸牌到贪心算法:NOIP经典题解与实战应用

本文深入解析NOIP经典题目均分纸牌问题,探讨贪心算法在信息学奥赛中的实际应用。通过生活场景类比、算法思想讲解、代码实现及优化技巧,帮助读者掌握贪心策略的核心原理与解题框架,并提供了环形均分纸牌等扩展问题的解法与实战训练建议。

weixin_33270920的博客 255

贪心算法总结

Greedy 贪心算法是一个非常常见的算法,根据字面意思,贪心就是贪婪,因此在贪心算法中,我们抛弃了大局观,转而去关注每一个局部子问题,对每一个局部子问题去求最优解,最后把所有的局部最优解结合起来作为我们最终的全局解。那么很直观的一个问题就是,局部最优解的结合很多时候并不一定是全局最优解,因此贪心算法是存在局限性的,不能去处理“最大”或者“最小”问题。作为一个AIerAIerAIer,贪心算法与我们的梯度下降算法很像,即有时候我们得到的只是局部最优,但有时候,我们也能得到全局最优或者全局最优解的近似解。 贪

qq_42791848的博客 1234

NOIP贪心算法算法

贪心算法。经典算法. OIER必备。 找的很辛苦。请关注

OI退役笔记-011:基础算法(四)贪心

〇、贪心的特点 1、贪心的选择:   贪心将原问题变为多个相似的但规模更小的子问题,而后的每一步都是当前看似最佳的选择,且这种选择只依赖于已做出的选择,不依赖未做出的选择。 2、最优子结构:   执行算法时,每一次得到的结果虽然都是当前问题的最优解(即局部最优解),当且仅当满足全局最优解包含局部最优解时,才能保证最终得到的结果是最优解。 一、贪心的例子 1、最优装载问题   给 n 个物品,第 i 个物品重量为 wi ,选择尽量多的物品,使得总重量不超过C。 【算法】   把所有物品按重量从小到大排序,每次

Rotch的博客 391

noip所有算法详解(非常全面)

本人精心整理自互联网,解压后约150MB,倍增、博弈、递归、递推、贪心、图论、动归、数论、搜索、数据结构(各种树形)、位运算、随机化、分治、字符串、排序、几何 当然noi的部分高级算法并未涉及,但针对noip是相当全面的!!

BQ4050开发进阶(二):Protections参数优化策略与实战解析

本文深入解析了BQ4050电池管理芯片中Protections参数的优化策略与实战方法。针对电压、电流、温度等核心保护功能,详细阐述了如何根据具体电芯特性、负载场景和环境因素,精细调整CUV、COV、OCC/OCD等阈值与延时,以在确保电池绝对安全的前提下,实现极致的用户体验与系统可靠性。

rgv234567的博客 480

加工生产调度

某工厂收到了n个产品的订单,这n个产品分别在A、B两个车间加工,并且必须先在A车间加工后才可以到B车间加工。 某个产品i在A、B两车间加工的时间分别为Ai、Bi。怎样安排这n个产品的加工顺序,才能使总的加工时间最短。这里所说的加工时间是指:从开始加工第一个产品到最后所有的产品都已在A、B两车间加工完毕的时间。第一行仅—个数据n(0<n<1000),表示产品的数量。 接...

weixin_30772105的博客 238

从信号到振镜:STM32F103 + XY2-100协议 + AM26LS31芯片的激光打标/雕刻系统信号链搭建指南

本文详细介绍了基于STM32F103微控制器和XY2-100协议的激光打标/雕刻系统信号链搭建方法。从数字振镜控制协议解析、AM26LS31差分驱动电路设计到信号完整性优化,提供了一套完整的解决方案,帮助工程师实现高精度激光控制系统的开发与调试。

weixin_42536058的博客 235

noip提高组写题心得——贪心4例

例1:火柴排队 这道题的话关系到一个叫排序不等式的东东,额这个东西的话其实我并没有学过,但是上网查一查,贴个证明下来: ②设有两个有序数组:  及 求证: (顺序和≥乱序和≥逆序和) 其中 是自然数的任何一个排列 证明:令 由题设易知  因为 故 所以  即左端不等式,类似可证明右端不等式 然后捏,这个求∑(ai-bi)^2其实就是求∑ai^2+bi^2-∑aibi那么就

maxtir的博客 1238

Ansys疲劳仿真:工程结构寿命评估的实战方法论

做了这么多年仿真,有个感受越来越深——静力学算得再漂亮,疲劳寿命预测不对,项目照样过不了评审。不是因为理论有多复杂,而是因为疲劳损伤的物理机制本身就带有统计属性,材料内部的微观缺陷分布、应力集中位置、载荷谱的随机性,每一项都能让结果偏移20%甚至更多。本文从实战出发,梳理Ansys疲劳仿真的核心流程,重点讲清楚载荷类型选择、S-N曲线处理、应力集中修正这几个最容易出问题的环节。疲劳仿真做好了,最大的收获不是跑出一个漂亮的Damage云图,而是对结构的真实薄弱环节建立起量化的认知。

keyanxiaobaigou的博客 524

华为灵衢UB总线介绍

华为发布"灵衢"(UB)超节点互联协议,旨在构建支持AI大模型计算的基础设施。该协议采用统一内存语义和对等架构,使设备可直接访问远程内存,实现资源池化。技术突破包括2.1微秒超低时延和TB级带宽,支持64节点、52万张昇腾卡的集群互联。相比传统RDMA,"灵衢"更注重系统级资源调度,而非单纯数据传输。华为开放技术规范,推动生态建设,已有厂商开发兼容IP核。"灵衢"可适应x86、RISC-V等架构,未来将扩展至百万卡规模集群。

技术引领业务创新 4420

拜托,别再问我贪心算法了!

前言 上篇一文学会动态规划解题技巧 被不少号转载了,其中发现有一位读者提了一个疑惑,在求三角形最短路径和时,能否用贪心算法求解。所以本文打算对贪心算法进行简单地介绍,介绍完之后我们再来看...

weixin_41385912的博客 752

无实习经验?IT应届生简历封神思路:把校园经历写成offer收割机

摘要: IT应届生无实习经历如何打造竞争力简历?本文揭秘“无实习简历封神指南”,通过四大步骤将校园经历转化为HR认可的硬核技能: 素材挖掘:课程设计、个人项目、社团活动、竞赛证书都是隐藏的“实战经验”,用STAR法则细化成果。 技能转化:匹配岗位JD关键词,用“动词+量化结果”包装经历(如“优化查询效率30%”)。 避坑指南:避免流水账、夸大技能或堆砌无关经历,聚焦技术能力与岗位需求。 核心逻辑:HR看重潜力而非经验,用校园经历证明学习能力、问题解决能力和技术落地能力。 无实习≠无竞争力,学会“翻译”经历,

通俗易懂学IT 421

【算法小讲堂】#1 贪心算法

算法小讲堂 | #1 贪心算法

cheer2333的博客 3978

机器学习实战5-天气预测系列:利用数据集可视化分析数据,并预测某个城市的天气情况

大家好,我是微学AI,最近天气真的是多变啊,忽冷忽热,今天再次给大家带来天气的话题,机器学习实战5-天气预测系列,我们将探讨一个城市的气象数据集,并利用机器学习来预测该城市的天气状况。该数据集包含年平均温度和湿度等信息。

微学AI的博客 1万+

RK3568 HDMI输出调试:分辨率切换与EDID解析

厂商信息(Vendor ID)显示器型号(Product ID)支持的分辨率列表色彩特性音频支持情况检查项方法HPD 信号EDID 读取当前模式TMDS 时钟PHY 状态。

小灰灰的博客 1482

24种NOIp常用的算法

列的比较宽泛。但相信对不太知道该干啥的萌新有一定指导作用 (想啥呢,教委这么搞下去学OI的人会少吧QAQ -------以下正文-------- 注意:推荐的题目不是模板题,模板题可以去luogu找。列出的是一些NOIp较难题,属于高级应用。 1、模拟 略。 2、预处理 很重要的技巧,但常被忽视。 e.g.: 大部分题目。 3、搜索 暴搜是一种信仰。 e.g.: ...

weixin_40676873的博客 8403

基于Python的IMF经济数据爬取与分析:从入门到实战

本文详细介绍了如何使用Python爬取国际货币基金组织(IMF)的经济数据,包括最新的爬虫技术、反反爬策略、数据解析与存储方法。文章从IMF数据源分析开始,逐步讲解如何构建一个完整的爬虫系统,并提供了详细的代码实现和优化建议。通过本文,读者将掌握爬取复杂国际组织数据的关键技术,并能将这些技术应用于其他类似的数据获取场景。关键词:Python爬虫、IMF数据、经济数据获取、数据清洗、反爬策略IMF Data (data.imf.org) - 主要数据门户。

2201_76125261的博客 1439

NOIP实用算法 目录

NOIP实用算法 教程 系列的第 1 篇 (本系列共12篇) NOIP实用算法 教程 NOIP实用算法 目录 NOIP实用算法 1.模拟方法 N

cnfnjatmzx的专栏 3106

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

C++算法之贪心算法

贪心算法是一种求解最优解问题的算法,它的核心思想是每一步都采取当前状态下最优的选择,从而最终得到全局最优解。它是C++重要的一种算法。本文会介绍贪心算法。

现役 OIer。 6765

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

【题解】【洛谷P1094】【贪心】—— [NOIP2007 普及组] 纪念品分组

本平台利用趣味性和互动性强的教学方式,旨在激发孩子们对编程的兴趣,培养他们的逻辑思维能力和创造力,让孩子们在轻松愉快的氛围中掌握编程知识,为未来科技人才的培养奠定坚实基础。为使得参加晚会的同学所获得 的纪念品价值相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品, 并且每组纪念品的价格之和不能超过一个给定的整数。通俗点说,较大的数已经占据了较大的空间,再放次大的数放进去的几率很小。你的任务是写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目。它们两个原理是一样的。

Pantheraonca的博客 2559

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

2012NOIP提高组之国王游戏求解与贪心算法

本文对国王游戏题目进行了解题思路详细分析与贪心算法的常用证明方法,并给出了题解的完整c++代码,同时在蓝桥杯和洛谷解题平台提交了代码,验证了代码正确性。

weixin_46846685的博客 956

C++算法·贪心

本文介绍了贪心算法的定义、特点、适用场景及局限性。贪心算法通过局部最优选择希望达到全局最优,适用于具有贪心选择性质和最优子结构的问题如最小生成树、最短路径等。文章以NOIP2018提高组铺设道路题目为例,展示了贪心思路和代码实现,并推荐了洛谷贪心题单。贪心算法虽高效但不保证所有问题全局最优,需正确性验证。

Gohldg的博客 1631

NOIP算法概论

之前高一参加比赛前,曾写过总结,主要是提醒自己NOIP所需要的基本算法,以及至少所需要掌握的数据结构。 当然,NOIP,最重要的算法,只有一个,THAT IS “搜索大法” 练好了搜索,今后的所有竞赛,题目哪怕拿不了满分,至少30+,说不定60+。自己脑补一下优化,100分就到手啦。。。 第一篇正儿八经的博客(别管前面那篇):请各位OIER们,一定一定,要练习搜索,必须练习搜索,而且搜索MU...

LORD_ZEUS的博客 643

【NOIP 2018 提高组】 货币系统 —— 贪心 + DP

本题的贪心证明比较困难,DP 部分比较简单,就是完全背包的变种,所以本文借鉴了洛谷上的第一篇题解,主要讲贪心的证明

m0_57883655的博客 1194

P5019 [NOIP2018 提高组] 铺设道路(贪心)

NOIP2018 提高组 D1T1。

2302_79440616的博客 1154
上一篇: 删数问题
下一篇: 最长递增子序列-Longest Increasing Subsequence
chiiis
博客等级 码龄14年 422粉丝 429原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值