NOI导刊-贪心与分治

合集下载

2018NOIP普及组初赛试题答案解析

2018NOIP普及组初赛试题答案解析

第二十四届全国青少年信息学奥林匹克联赛初赛普及组C++语言试题竞赛时间:2018年10月13日14:30~16:30选手注意:●试题纸共有7页,答题纸共有2页,满分100分。

请在答题纸上作答,写在试题纸上的一律无效。

●不得使用任何电子设备(如计算器、手机、电子词典等)或查阅任何书籍资料。

一、单项选择题(共15题,每题2分,共计30分;每题有且仅有一个正确选项)1.以下哪一种设备属于输出设备:()A.扫描仪B.键盘C.鼠标D.打印机解析:这是一道送分题,会就会,不会就不会。

所以选D。

2.下列四个不同进制的数中,与其它三项数值上不相等的是()。

A.(269)16B.(617)10C.(1151)8D.(1001101011)2解析:这题考核的是进制转换。

(269)16=2*16^2+6*16^1+9*16^0=617,(1151)8=1*8^3+1* 8^2+5*8^1+1*8^0=617,而(1001101011)2=619。

所以选D。

3.1MB等于()。

A.1000字节B.1024字节C.1000X1000字节D.1024X1024字节1KB=1024B1MB=1024KB解析:这题考核的是字节之间的转换。

1MB=1024KB=1024*1024B。

所以选D。

4.广域网的英文缩写是()。

NB.WANC.MAND.LNA解析:这题是送命题,,会就会,不会就不会。

WAN全称为Wide Area Network。

所以选B。

5.中国计算机学会于()年创办全国青少年计算机程序设计竞赛。

A.1983B.1984C.1985D.1986解析:这题是送命题,会就会,不会就不会。

NOI是全国青少年信息学奥林匹克竞赛(National Olympiad in Informatics)的简称。

NOI是国内包括港澳在内的省级代表队最高水平的大赛,自1984年至今,在国内包括香港、澳门组织竞赛活动。

所以选B。

6.如果开始时计算机处于小写输入状态,现在有一只小老鼠反复按照CapsLock、字母键A、字母键S、字母键D、字母键F的顺序循环按键,即CapsLock、A、S、D、F、CapsLock、A、S、D、F、……,屏幕上输出的第81个字符是字母()。

NOIP提高组初赛历年试题及答案选择题篇

NOIP提高组初赛历年试题及答案选择题篇

NOIP提高组初赛历年试题及答案选择题篇单项选择题(共10-15题,每题1.5分,共计15-22.5分。

每题有且仅有一个正确选项。

)注:答案在末尾NOIP2011-1.在二进制下,1011001+()=1100110。

同普及组NOIP2011-1 A.1011 B.1101 C.1010 D.1111NOIP2011-2.字符“A”的ASCII码为十六进制41,则字符“Z”的ASCII码为十六进制的()。

A.66B.5AC.50D.视具体的计算机而定NOIP2011-3.下图是一棵二叉树,它的先序遍历是()。

A.ABDEFCB.DBEFACC.DFEBCAD.ABCDEFNOIP2011-4.寄存器是()的重要组成部分。

同普及组NOIP2011-6A.硬盘B.高速缓存C.内存D.中央处理器(CPU)NOIP2011-5.广度优先搜索时,需要用到的数据结构是()。

同普及组NOIP2011-11A.链表B.队列C.栈D.散列表NOIP2011-6.在使用高级语言编写程序时,一般提到的“空间复杂度”中的空间是指()。

同普及组NOIP2011-12A.程序运行时理论上所占的内存空间B.程序运行时理论上所占的数组空间C.程序运行时理论上所占的硬盘空间D.程序源文件理论上所占的硬盘空间NOIP2011-7.应用快速排序的分治思想,可以实现一个求第K大数的程序。

假定不考虑极端的最坏情况,理论上可以实现的最低的算法时间复杂度为()。

A.O(n2) B.O(n log n) C.O(n) D.O(1)NOIP2011-8.为解决web应用中的不兼容问题,保障信息的顺利流通,()制定了一系列标准,涉及HTML、XML、CSS等,并建议开发者遵循。

A.微软B.美国计算机协会(ACM)C.联合国教科文组织D.万维网联盟(W3C)NOIP2011-9.体育课的铃声响了,同学们都陆续的奔向操场,按老师的要求从高到低站成一排。

2024年CSP NOIP 夏令营课程设计

2024年CSP NOIP 夏令营课程设计
2024 CSP NOIP 夏令营 课程设计
2024 夏令营各营列表及说明(不分年级只分难度)务必选取本人匹配的营:a、请依照营别说明和对应课表选班;b、请进行学业水平测试选班;c、学业顾问推荐。
CSP-J 精英营
7 月 15-21 济南
系统学习过 CSP-J 知识体系,能用数据结构和算法写简单程序。但做题量不足、 难度不够、应用及变形能力 弱。
对算法知识进行梳理并通过补充大量经典例题增加难度。 课程内容覆盖 J 组的所有内容, 并还会涉及少量必要的 S 组的拓展内容。目标 200 分以上
4890
CSP-J 刷题实战 梳理营
7 月 23-30 济南
对 J 组知识已经相对熟悉, 知识储备完整, 但刷题量小、 刷题质量不高。利用知识储备分析、构造、解决问题能力不足、 实战能力弱
全模块。通过训练突破没有思路或有思路不会写的瓶颈,“快速审题+解题思路+代码实现+算法模型的构建 ”为主, 着力于分析能力、 构造能力、 解题能力的培养。目标具备 200 分以上能力
4890
S NOIP 刷题实 战梳理营
7 月 23-8 月 3 济南
对 S NOIP 知识已经相对熟悉, 知识储备完整但系统 性不强 。 缺少模块专项模拟和全真模拟 , 分析、构造、解决问题能力不足 , 实战能力弱
系统学习过 CSP-J 知识体系,能用数据结构和算法写简单 程序。但做题量不足、 难度不够、应用及变形能力弱。
对算法知识进行梳理并通过补充大量经典例题增加难度。 课程内容覆盖 J 组的所有内 容,并还会涉及少量必要的 S 组的拓展内容。目标 200 分以上
注:以上课程可能根据学生实际情况略有微调,以实际发放的课表为准。每课时 50 分钟。

NOIP如何取得好成绩

NOIP如何取得好成绩

重要的算法:
NOIP的基本难度分布是这样的: 6.二分答案
二分答案在实质上是一种枚举的优化, 一般采用迭代的写法, 但是有的时候也用递归,因为要递归的层数一般很少。 二分答案一般适用于当所要求的答案递增时可用, 时间复杂度一般来说都是O(log2n)。
重要的算法:
NOIP的基本难度分布是这样的:
【NOIP省选知识点汇总】
三、数学
考前的时间安排
2、十一月份复赛 如果可以的话,应该有两周的时间停课,专
心来准备NOIP的复赛,争取取得NOIP一等奖,
两周的时间一般对接下来的高考或期末的学 习成绩影响很小。(有许多同学甚至一个月不参 加文化课的学习,也不影响文化课成绩)
注:当然是否停课要看个人的情况而定哟!NOIP一等奖一般 是指提高组的一等奖。
2、 递推与递归,贪心法,二分法
3、 搜索算法(剪枝)
4、 动态规划(线性动态规划、、背包问题)
NOIP学习进阶
第四阶段:再次狂做题巩固第三阶段的内容,基本上都 是自主研究和学习,力争把这20年来全国赛,分区赛的 所有题目全部做一次,背熟了!!!
第五阶段:学习高级数据结构和算法,进一步提升,用 ACM的题目来练手。《信息学奥赛一本通提高版》 ---提高组(高中组)
7.计数 计数这一技巧可以在数据的规模较小, 而对时间复杂度的要求很低时可用, 基于计数排序或者哈希表的原理, 这个技巧可以在近似O(1)的时间内找到数据。
重要的算法:
NOIP的基本难度分布是这样的:
8.数论 NOIP并不考太过难的题目, 比如欧拉函数φ(n)之类的东西, 一般来说只会考与质数相关的基本数论, 并不会太难,就算是指数筛选也鲜有用O(n)算法的, 质数判定之类的问题更是一个O(sqrt(n))的算法就能搞定, 一般都出在第一到二题,或者说也就是一些非主要考点罢了。

浅谈贪心算法

浅谈贪心算法

贪心算法贪心算法是一种用来求最优解的算法,主要思想是将问题分为数个步骤,用一个贪心标准逐步求出每一步骤的最优解,最终产生全局最优解。

贪心算法的优点是效率高,缺点是最终产生的解不一定是最优解。

1.均分纸牌(NOIP2002提高组第1题)问题描述:有 N 堆纸牌,编号分别为 1,2,…, N。

每堆上有若干张,但纸牌总数必为 N 的倍数。

可以在任一堆上取若干张纸牌,然后移动。

移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上;在编号为 N 的堆上取的纸牌,只能移到编号为 N-1 的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。

现在要求用最少的移动次数S使每堆上纸牌数都一样多。

输入格式:Na[1], a[2], …, a[N]输出格式:S算法分析:从第1堆到第N堆纸牌,按从左到右的顺序,若第i堆纸牌数a[i]大于平均数k,则将多出的纸牌移到第i+1堆上;若a[i]小于k,则将缺少的纸牌数移到第i+1堆上(缺少的纸牌数可由右侧传递给左侧,次数相同)。

例:n=4 a[1..4] = 4 6 10 84 ——〉 6 ——〉 10 ——〉 8-3 -4 -1(等于右给左2)(右给左4)(右给左1)源程序:Vara: Array[1..100]Of Integer;i, n, t, s: Integer;BeginReadLn(n);For i := 1 To n Do Read(a[i]);For i := 1 To n Do t := t + a[i];t := t Div n; {求平均数}For i := 1 To n-1 DoIf a[i] <> t ThenBeginInc(s); {计数}a[i+1] := a[i+1] + (a[i] - t);End;WriteLn(s);End.在用贪心算法解题时,需要注意两方面,一是问题是否适用于贪心算法,二是应选用怎样的贪心标准。

贪心算法、分治算法、动态规划算法间的比较.doc

贪心算法、分治算法、动态规划算法间的比较.doc

题目:贪心算法、分治算法、动态规划算法间的比较贪心算法:贪心算法采用的是逐步构造最优解的方法。

在每个阶段,都在一定的标准下做出一个看上去最优的决策。

决策一旦做出,就不可能再更改。

做出这个局部最优决策所依照的标准称为贪心准则。

分治算法:分治法的思想是将一个难以直接解决大的问题分解成容易求解的子问题,以便各个击破、分而治之。

动态规划:将待求解的问题分解为若干个子问题,按顺序求解子阶段,前一子问题的解,为后一子问题的求解提供了有用的信息。

在求解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。

依次解决各子问题,最后一个子问题就是初始问题的解。

二、算法间的关联与不同1、分治算法与动态规划分治法所能解决的问题一般具有以下几个特征:①该问题的规模缩小到一定程度就可以容易地解决。

②该问题可以分为若干个较小规模的相似的问题,即该问题具有最优子结构性质。

③利用该问题分解出的子问题的解可以合并为该问题的解。

④该问题所分解出的各个子问题是相互独立的且子问题即之间不包含公共的子问题。

上述的第一条特征是绝大多数问题都可以满足的,因为问题的计算复杂性一般是随着问题规模的增加而增加;第二条特征是分治法应用的前提,它也是大多数问题可以满足的,此特征反映了递归思想的应用;第三条特征是关键,能否利用分治法完全取决于问题是否具有第三条特征,如果具备了第一条和第二条特征,而不具备第三条特征,则可以考虑贪心算法或动态规划算法;第四条特征涉及到分治法的效率,如果各个子问题不是独立的,则分治法要做许多不必要的工作,重复地解公共的子问题。

这类问题虽然可以用分治法解决,但用动态规划算法解决效率更高。

当问题满足第一、二、三条,而不满足第四条时,一般可以用动态规划法解决,可以说,动态规划法的实质是:分治算法思想+解决子问题冗余情况2、贪心算法与动态规划算法多阶段逐步解决问题的策略就是按一定顺序或一定的策略逐步解决问题的方法。

信息学奥林匹克竞赛指导之基础算法—贪心算法

信息学奥林匹克竞赛指导之基础算法—贪心算法
超过C的情况下让总价值最高。每一个物体可以只取走一部分,价值和
重量按比例计算。
7
-贪心算法
贪心算法的经典实例
• 思路点拨:本问题是在上一个问题的基础上增加了价值项,所以不能简
单地向上一题那样先选出轻的(轻的可能其价值也小),也不能先拿价
值大的(它可能特别重),而应该综合考虑两个因素。一种直观的贪心
可乘两个人。求用最少的船载所有人的方案。
8
-贪心算法
贪心算法的经典实例
• 思路点拨:考虑最轻的人i,他应该和谁一起乘呢?如果每个人都不能和
他一起乘,则只能每人乘一艘船。否则他应该选择能和他一起乘的人中
最重的一个人j。这样的选择只是让“眼前”的浪费最少,因此它是一种
贪心策略。
• 证明:
• 情况1:i不和任何一个人同乘一艘船,那么可以把j拉过来和他一起乘,总船数不会
法不从整体最优考虑,它所做出的选择只是局部最优解。
3
-贪心算法
贪心算法的概念及其特点
• 贪心算法是从问题的初始状态出发,通过若干次的贪心选择而得
到的最优值的一种求解问题的策略。
• 特点:
• 贪心选择:所谓贪心选择是指应用同一规则,将原问题变为一个相似的
但规模更小的子问题,而后的每一步都是当前看似最佳的选择,且这种
29
-贪心算法
贪心算法的经典应用-3
• 【输出格式】
• 对每组测试数据输出一个数字,表示要浇灌整块草坪所需喷头数
目的最小值。如果所有喷头都打开还不能浇灌整块草坪,则输出1。
• 【样例输入】
•3
• 8 20 2
•53
30
-贪心算法
贪心算法的经典应用-3


NOI导刊-贪心与分治

NOI导刊-贪心与分治

例题2: INT(整数区间)
定义 一个整数区间[A,B],A﹤B,是一个从A 开始,至B结束的连续整数的集合。 任务是从文件中读取区间的个数及其对它们的 描述,找出满足下述条件的所含元素个数最 少的集合中元素的个数:对于每一个区间, 都至少有两个不同的整数属于该集合。
输入:
文本文件INT.IN的首行包括区间的数目N, 1≦N≦10000。接下来的N行,每行包括两个 整数A,B,被一空格隔开,0≦A≦B≦10000 ,它们是某一个区间的开始值和结束值。
(N<=200000,M<=10000)
例题3:零件分组
某工厂生产一批棍状零件,每个零件都有一定的长度(Li)和重量(Wi)。 现在为了加工需要,要将它们分成若干组,使每一组的零件都能排成一个长 度和重量都不下降(若i<j,则Li<=Lj,Wi<=Wj)的序列。请问至少要分成 几组?
输入:第一行为一个整数N(N<=1000),表示零件的个数。第二行有N对正 整数,每对正整数表示这些零件的长度和重量,长度和重量均不超过10000 。
输出:仅一行,即最少分成的组数。 样例(STICK.IN) 5 8438239735 STICK.OUT 2
例题4:乘船问题(HNCOI)
有N个人需要乘船,而每船最多只能载 两人,且必须同名或同姓。求最少需要多 少条船。
问题分析
看到这道题,很多人都会想到图的数据结构 :将N个人看作无向图的N个点,凡同名或同 姓的人之间都连上边。
首先,由于图中任两个连通分量都是 相对独立的,也就是说任一条匹配边的 两顶点,都只属于同一个连通分量。因 此,我们可以对每个连通分量分别进行 处理,而不会影响最终的结果。
同时,我们还可以对需要船只s的下限进行估 计:

贪心,递归,分治

贪心,递归,分治

分析 凭直觉可以知道,如果每次选择具有最早完 成时间的活动,并且这些活动相容,那么最后 的活动是否一定最多呢? 我们可以用数学归纳法证明..在这略.. 我们将这些活动按结束时间的非递减排序. 得到活动集合E={1,2,3,…n}.那么我们首先 选择活动1放入当前集合A中,下面我们依次 从集合E选择活动j,若A中的当前活动为i,j能 够加入到A,当且仅当sj≥fi; 问题得到解决,时间复杂度为O(nlgn+n);其 中排序O(nlgn).扫描一遍用O(n);
递归
先来看一个例子 Fibonacci数列 数列 无穷数列1,1,2,3,5,8,13,21,34, 55,…,被称为Fibonacci数列。它可以递归 地定义为:
n=0 1 F (n) = 1 n =1 F ( n − 1) + F ( n − 2 ) n > 1
递归
这个题目中,若想求出F(n),那么必须先求出F(n-1) 和F(n-2).这样我们可以想到,是否可以用求F(n)的 方法来求F(n-1)和F(n-2)呢,明显可以,只要改变参 数就可以了。 第n个Fibonacci数可递归地计算如下: int fibonacci(int n) { if (n <= 1) return 1; return fibonacci(n-1)+fibonacci(n-2); }
贪心,递归,分治
主讲人:张延增
贪心
贪心算法是使所做的选择看起来是当前最佳 的,期望通过所做的局部最优选择来产生出一 个全局的最优解. 算法导论第16章专门讲贪心算法,其中最经典 的例子就是huffma编码.活动安排问题,非0-1 背包问题.最短路,最小生成树 下面我们看一些很经典的例子
部分背包问题

NOI导刊基础算法策略.ppt

NOI导刊基础算法策略.ppt
⑴可预先确定每个状态的元素个数n;
⑵状态元素a1,a2,…,an的可能值为一个连续的值域。 设
ai1— 状 态 元 素 ai 的 最 小 值 ; aik— 状 态 元 素 ai 的 最 大 值 (1≤i≤n) , 即 a11≤a1≤a1k,a21≤a2≤a2k, ai1≤ai≤aik,……,an1≤an≤ank
If dis[knight[kk].x,knight[kk].y,x,y]<min then begin
Min:= dis[knight[kk].x,knight[kk].y,x,y];
Mink:=k;
End; End; Now:= all-mink武士走到汇合点的距离+ mink武士走到汇聚 点的距离+ 国王走到汇聚点的距离+从汇聚点到汇合点的距离; Best:=min(best,now) End;
枚举方法的优化
枚举算法的时间复杂度:状态总数*单个状态的耗时 主要优化方法:
⑴ 减少状态总数 ⑵ 降低单个状态的考察代价 优化过程从以下几个方面考虑: ⑴ 枚举对象的选取 ⑵ 枚举方法的确定 ⑶ 采用局部枚举或引进其他算法
枚举算法的应用
例题1:二进制数的分类
若将一个正整数转化为二进制数后,0的个数多于 1的个数的这类数称为A类数,否则称为B类数。 例如:
基础算法策略
长沙市第一中学 曹利国
第一部分
枚举策略
枚举策略的基本思想
枚举法,又称穷举法,指在一个有 穷的可能的解的集合中,一一枚举 出集合中的每一个元素,用题目给 定的检验条件来判断该元素是否符 合条件,若满足条件,则该元素即 为问题的一个解;否则,该元素就 不是该问题的解。
枚举策略的基本思想
(1)一次只能移一个圆盘; (2)圆盘只能在三个柱上存放; (3)在移动过程中,不允许大盘压小盘。

noip导刊

noip导刊

将横分割线和竖分割线分别按大至小快排一 遍。使得切刀按从左至右从上至下顺序。 记F[I,j]表示切了前I条横分割线,前J条横分 割线的最小代价。 每横线切I刀,总共分为I+1块横块,每竖线 切J刀,总共分为J+1块横块。则有
F[I,j]=min{F[i-1,j]+row[i]* (j+1),F[I,j-1]+line[j]*(i+1)}
row[i]与line[j]代表横竖切刀代价,最后答案 即为F[n-1,m-1]。 时间复杂度是O(N^2)。
Problem #2: 牛宫(long) 题意简述 求一个矩阵中平均数大等于0的最大子矩阵 的面积。
解题思路
首先,平均数大于等于0等价于和大于等于0, 这样便于处理。 方法1:O(N^6)枚举获得部分分。
例:设[A, B]表示路径的权值和为A,通过了 B条边。假设从i -> k存在着两条路径L1[2, 3]以及 L2[8, 10],从k -> j存在着两条路径L3[1, 2]以及 L4[51, 100],很明显i -> k的最小密度路径是L1, k -> j的最小密度路径是L3,但是i -> k -> j的最小 密度路径却是L1 + L4。 有否办法去掉这个除法的影响? 回到问题特性,是有向无环图,一条路径最 多只能经过N-1条边,于是我们可以对边数进行 枚举,即把答案的分母枚举了,剩下的就是让答 案的分子最小化(答案是 权值和/边数),这就 回到我们熟悉的问题:求最短。
NOIP模拟赛10月4日分析
Problem #1: 矩形分割(cut)简单题 题意简述 给出一个N*M的矩阵中N-1条横线和M-1条竖 线的切割代价,求把矩形分割成1*1的小块的最小 代价。

信息奥林匹克竞赛之贪心算法 共29页

信息奥林匹克竞赛之贪心算法 共29页
}
int main(){ scanf("%d",&n); for(i=1;i<=n;i++){ 读取n个数 }
{将n个数使用cmp()函数排序}
{按排好的顺序输出(中间无空格)} }
线段覆盖
• 题目描述:
• 在一个数轴上有n条线段,现要选取其中k条线段使得这k条线段两两没有重合 部分(端点可以重合),问最大的k为多少
更优方案: 7+3+8+7+5=30
不符合
贪心选择性质
分析
• 当不能100%确定一个贪心算法正确时,在使用之 前,就应该尝试证明它的不正确性。
• 要证明其不正确,一种最简单的方法就是举一个 反例。
• 其实,要严格证明一个贪心算法的正确性是很困 难的,目前最有效的一种方法叫“矩阵胚理论”, 但是很复杂,中学生不可能理解。
在从第i1堆中取出纸牌补充第i堆的过程中可能会出现第i1堆的纸牌数小于零ai1aiv0如n3三堆纸牌数为1227这时v10为了使第一堆数为10要从第二堆移9张纸牌到第一堆而第二堆只有2张纸牌可移这是不是意味着刚才使用的贪心法是错误的呢
武松打老虎
问题描述: 曾经因打虎而文明的武松在x年后接到了景阳冈动物园的求助信,
那么,如何证明以上贪心策略的正确性呢
因为右端点坐标最小,可以保证所有与这条线段没有公共部分的线
段都在这条线段的右边,且所有与这条线段有公共部分的线段两两之间 都有公共部分。
又根据题意,在这些有公共部分的线段中,最后只能保留一条。显
然,右端点坐标最小,对后面线段的影响最小,所以,应保留这条线段 。
每次取左端点坐标 最小的行不行?
• 武松剩下的体力值越大,能打死的老虎就越多。使用贪心选择(每次 选择剩下的老虎中体力最少的),能使武松剩下的体力最大。这种贪 心选择,能保证全局最优,即能保证打死最多数量的老虎。

信息学奥赛NOIP教程基于贪心的算法和应用

信息学奥赛NOIP教程基于贪心的算法和应用
writeln;
经典例题
【例5】均分纸牌(NOIP 2002) 有N堆纸牌,编号分别为1,2,……,N。第i
堆有a[i]张纸牌(a[i]≤10000),但纸牌总数必 为N的倍数。可以在任一堆上取若干张纸牌,然后 移动。移牌规则为:在编号为1堆上取的纸牌,只 能移到编号为2的堆上;在编号为N的堆上取的纸 牌,只能移到编号为N-1的堆上;其他堆上取的 纸牌,可以移到相邻左边或右边的堆上。现在要 求找出一种移动方法,用最少的移动次数使每堆 牌数都一样多。
贪心算法的特点
【分析】 有以下几种策略可供选择: (1)每次挑选价值最大的物品装入背包, 得到的结果是否最优? (2)每次挑选所占空间最小的物品装入是 否能得到最优解? (3)每次选取单位容量价值最大的物品。
贪心算法的特点
解题一般步骤: 1、设计数据找规律; 2、进行贪心猜想; 3、正确性证明(严格证明和一般证明) ★一般证明:列举反例; ★严格证明:数学归纳和反证法; 4、程序实现。
经典例题
for i:=1 to n-1 do for j:=i+1 to n do if num[i]+num[j]<num[j]+num[i] then begin temp:=num[i]; num[i]:=num[j]; num[j]:=temp end;
for i:=1 to n do write(num[i]);
经典例题
结论: 每一次删除的数字应该是这个数字序列
中最左边递减序列的第一个数字。具体操作 为,按高位到低位的方向搜索递减区间。若 不存在递减区间,则删除尾数字,否则删除 递减区间的首数符,这样就形成一个最小的 数。
重复上述规则,直到删除S个数字为止。
经典例题

NOIP基础算法——贪心和分治

NOIP基础算法——贪心和分治
②、若f(a)*f((a+b)/2)<0,则由题目给出的定理可知根在区 间(a,(a+b)/2)中,故对区间重复该过程;
③、若f(a)*f((a+b)/2)>0,则必然有f((a+b)/2)*f(b)<0,根在 ((a+b)/2,b)中,对此区间重复该过程。
执行完毕,就可以得到精确到0.0001的根。
二、分治法的适用条件
能使用分治法解决的问题,它们一般具备以下几个特征: ①该问题可分解成若干相互独立、规模较小的相同子问题; ②子问题缩小到一定的程度就能轻易得到解; ③子问题的解合并后,能得到原问题的解;
分治法在信息学竞赛中应用非常广泛,使用分治策略能生成 一些常用的算法和数据结构,如快排、最优二叉树、线段树 等;还可以直接使用分治策略,解决一些规模很大、无法直 接下手的问题。
方法1:朴素算法
在看完试题以后,我们不难想到一个非常简单的算 法——穷举算法,即对数组中任意的两个元素进行 判断,看它们是不是构成“逆序对”,因此这种算 法的时间复杂度为O(N2)。 c:=0; for i:=1 to n -1 do for j:=i+1 to n do if a[i]>a[j] then c:=c+1;
if(a[i]>a[j])then begin temp[p]:=a[j];inc(p);inc(j);end else begin temp[p]:=a[i];inc(p);inc(i);end
while(i<=mid)do begin temp[p]:=a[i]t;=right)do begin temp[p]:=a[j];inc(p);inc(i);end for i:=left to right do a[i]:=temp[i]; End;

信息学竞赛(noip) 枚举、模拟、贪心

信息学竞赛(noip) 枚举、模拟、贪心

LED
读数练习
• 输入一个数,输出这个数的拼音读法。 • 12 3456 7009读为:shi er yi san qian si bai wu shi liu wan qi qian ling jiu • 10010读为:yi wan ling yi shi • 100000读为:shi wan • 2000读为:er qian
优化
改变枚举次序 改变比较情况时所花的时间 剪枝--减少边界条件的枚举情况. 在本例中可以优化的地方为 确定p和q的取值 范围, • 对于确定的m,p和q为质数,所以p和q最多取 到sqrt(m); • 因为m<=100000, sqrt(100000)=316.999, • 所以p和q最多取到317 • • • •
for a1←a11 to a1k do
fo a2←a21 to a2k do for ai←ai1 to aik do …………………… ……………………
for an←an1 to ank do
if 状态(a1,…,ai,…,an)满足检验条件 then 输出问题的解;
枚举法优缺点
枚举法的优点: ⑴由于枚举算法一般是现实生活中问题的‚直译‛,因此比较直观,易于 理解; ⑵由于枚举算法建立在考察大量状态、甚至是穷举所有状态的基础上,所 以算法的正确性比较容易证明。
分析
• 我们分析一下表示时钟时针初始位置的数码j(0≦j≦3)与时刻的 对应关系: • 0——12点 • 1——3点 • 2——6点 • 3——9点 • 每移动一次,时针将顺时针旋转90度。由此我们可以得出: • 对于任意一个时钟i(1≦i≦9)来说,从初始位置j出发至少需要 Ci=(4-j) mod 4次操作,才能使得时针指向12点。而对每种移动 方法要么不采用,要么采用1次、2次或3次,因为操作四次以后, 时钟将重复以前状态。因此,9种旋转方案最多产生49个状态。

信息学奥赛NOIP贪心

信息学奥赛NOIP贪心

4,3
2,2
4
4
1
5 3
【分析】 贪心:每次访问的位置= max{max( 已访问的最远位置的左 边疲劳值),max(已访问的最远位置到某个位置距离*2+疲劳 值)}
起点
疲劳值
已访问的 最远位置 距离*2+疲劳值
【例2】电池的寿命(noip-openjudge 4.6算法之贪心) 小S新买了一个掌上游戏机,这个游戏机由两节5号电池供电。 为了保证能够长时间玩游戏,他买了很多 5 号电池,这些电池的生 产商不同,质量也有差异,因而使用寿命也有所不同,有的能使用 5个小时,有的可能就只能使用3个小时。显然如果他只有两个电池 一个能用 5 小时一个能用 3 小时,那么他只能玩 3 个小时的游戏,有 一个电池剩下的电量无法使用,但是如果他有更多的电池,就可以 更加充分地利用它们,比如他有三个电池分别能用 3 、3 、 5 小时, 他可以先使用两节能用 3 个小时的电池,使用半个小时后再把其中 一个换成能使用 5 个小时的电池,两个半小时后再把剩下的一节电 池换成刚才换下的电池(那个电池还能用 2.5 个小时),这样总共 就可以使用5.5个小时,没有一点浪费。 现在已知电池的数量和电池能够使用的时间,请你找一种方案 使得使用时间尽可能的长。
1 7
4,3
2,2 8,7
4
4 12
1
5 11
【输入样例2】
【输出样例2】
12 17 21 24 27
5
1 2 2 4 5
5 4 3 4 1
A
起点 S 疲劳值
5
1 5
4,3
2,2 4,3
4
4
1
5 3
【输入样例2】
【输出样例2】

(NOIP)信息学竞赛 贪心算法 基础 提升

(NOIP)信息学竞赛 贪心算法 基础 提升

0,1背包问题
给定一个最大载重量为M的卡车和 种动物 给定一个最大载重量为 的卡车和N种动物.已 的卡车和 种动物. 知第i种动物的重量为 种动物的重量为Wi,其最大价值为Vi, 知第 种动物的重量为 ,其最大价值为 ,设 均为整数, 定M,Wi,Vi均为整数,编程确定一个装货方 , , 均为整数 使得装入卡车中的所有动物总价值最大. 动物总价值最大 案,使得装入卡车中的所有动物总价值最大.
算法?
按贪心法,有反例. 设N=3,卡车最大载重量是100,三种动 物A,B,C的重量分别是40,50,70, 其对应的总价值分别是80,100,150.
例2 排队打水问题
个人排队到R个水龙头去打水 有N个人排队到 个水龙头去打水,他们装满水 个人排队到 个水龙头去打水, 桶的时间为T1, , , 为整数且各不相等 为整数且各不相等, 桶的时间为 ,T2,…,Tn为整数且各不相等, 应如何安排他们的打水顺序才能使他们花费的 时间最少? 时间最少?
例5:d-规则问题
对任意给定的m(m∈N 满足m<n m<n, 对任意给定的m(m∈N+)和n(n∈N+),满足m<n,构 造一初始集合: 造一初始集合:P={x|m≤x≤n,x∈N+}(m,n≤100) 现定义一种d规则如下:若存在a∈P,且存在 现定义一种d规则如下:若存在a∈P, a∈P ,K>1,使得K a∈P,则修改P P=PK∈N+ ,K>1,使得K×a∈P,则修改P为:P=P{y|y=s× 并称该d规则具有分值a {y|y=s×a,s∈N+ } ,并称该d规则具有分值a. 现要求编制一个程序,对输入的m,n m,n值 现要求编制一个程序,对输入的m,n值,构造相应 的初始集合P 每应用一次d 的初始集合P,对P每应用一次d规则就累加其相应 的分值, 分值的d规则序列, 的分值,求能得到最大累加 分值的d规则序列, 输出每次使用d规则时的分值和集合p的变化过程. 输出每次使用d规则时的分值和集合p的变化过程.

[NOI2017]蔬菜贪心

[NOI2017]蔬菜贪心

[NOI2017]蔬菜贪⼼题解: ⾸先每天蔬菜会变质这点并不好处理,我们考虑让时间倒流,从后向前处理,这样的话就相当于每天都会得到⼀定量的蔬菜。

这样做有什么好处呢? 我们可以发现⼀个性质:如果从后向前贪⼼卖菜,那么因为现在可以卖的菜,以后⼀定还可以卖(因为变成了得到菜),因此贪⼼就是对的了。

因此我们⽤堆维护⼀下,从后向前贪⼼的卖菜,每次优先卖价格⾼的,第⼀次卖的菜价格要加上奖励的贡献,并且只能先卖⼀个,因为卖完这⼀个之后的同种菜没有奖励了,相当于贡献有变化。

这样向前⼀直贪到第⼀天,于是我们就得到了卖1 ~ 100000天的最⾼收⼊。

那么已知1到100000的最⾼收⼊,如何利⽤之前的决策信息快速的得知1到99999的最⾼收⼊呢? 我们发现,这2者之间唯⼀的差别就是少买了最多m个蔬菜。

那么我们已知我们已经卖了have个蔬菜,已知1到now这么多天最多卖m∗now个蔬菜,那么如果have>m∗now,我们就要舍弃部分蔬菜使得have<=m∗now成⽴。

⽤堆维护,每次撤销卖价最低的蔬菜即可,注意如果撤销的这个蔬菜是剩下的最后⼀个了,那么代价要加上奖励的代价。

为什么这样是对的呢? 因为如果这个菜是在后⾯被卖出的话,前⾯肯定也可以卖,所以如果我们撤销了某天卖出的蔬菜,可以看做在这天后⾯卖出的蔬菜被挤上来顶替了这个被撤销的蔬菜,于是代价就会始终等价于撤销了最后⼀天卖出的蔬菜。

1 #include<bits/stdc++.h>2using namespace std;3#define R register int4#define AC 1001005#define LL long long67int n, m, k, can;//存下浪费了多少的卖菜名额8const int maxn = 100000;9 LL ans[AC], last[AC], sum[AC], d[AC], have[AC], v[AC], s[AC], c[AC];10int sta[AC], top;11//每⼀天的答案,每种菜最后⼀天出现是在哪⼀天,那天有多少这种菜,d表⽰以后每天增加多少12//have表⽰这种菜现在卖出了多少,a表⽰卖菜的基础收益,s表⽰额外收益,c表⽰初始库存13int Head[AC], Next[AC], date[AC], tot;14struct node{15 LL v;16int id;17 };1819struct cmp2{//⼩根堆20bool operator () (node a, node b){ return a.v > b.v;}21 };2223struct cmp{//⼤根堆24bool operator () (node a, node b){return a.v < b.v;}25 };2627 priority_queue<node, vector<node>, cmp> q;28 priority_queue<node, vector<node>, cmp2> q2;2930 inline int read(){31int x = 0;char c = getchar();32while(c > '9' || c < '0') c = getchar();33while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();34return x;35 }3637 inline void add(int f, int w){38 date[++ tot] = w, Next[tot] = Head[f], Head[f] = tot;39 }4041void pre()42 {43 n = read(), m = read(), k = read();44for(R i = 1; i <= n; i ++)45 {46 v[i] = read(), s[i] = read(), c[i] = read(), d[i] = read();47if(d[i])48 {49 last[i] = c[i] / d[i] + 1, sum[i] = c[i] - (c[i] / d[i]) * d[i];50if(!sum[i]) sum[i] = d[i], last[i] --;51 add(last[i], i);//把这个菜挂在第⼀次出现的地⽅52 }53else last[i] = maxn, sum[i] = c[i], add(maxn, i);54 }55 }5657void get()//从后向前贪⼼,⼩根堆维护撤销58 {59for(R i = 1; i <= n; i ++)//把卖出去的菜压⼊栈中60if(have[i] == 1) q2.push((node){v[i] + s[i], i});61else if(have[i]) q2.push((node){v[i], i});62for(R i = maxn - 1; i; i --)//向前撤销63 {64 ans[i] = ans[i + 1];//初始状态65 LL y = m;66if(i * m >= can) continue;67else y = can - i * m, can -= y;68while(y && !q2.empty())69 {70 node x = q2.top();71if(have[x.id] == 1) ans[i] -= x.v, q2.pop(), -- y;//如果只剩⼀个了就要弹出去了72else73 {74if(have[x.id] > y)//如果反正取不完的话就随便取,否则就要注意不能取完了75 {76 have[x.id] -= y, ans[i] -= x.v * y, y = 0;77if(have[x.id] == 1)78 q2.pop(), x.v += s[x.id], q2.push(x);79 }80else81 {82 ans[i] -= x.v * (have[x.id] - 1), y -= (have[x.id] - 1);83 have[x.id] = 1, q2.pop(), x.v += s[x.id], q2.push(x);84 }85 }86 }87 }88 }8990void build()//从后向前贪⼼,⼤根堆维护取值91 {92for(R i = maxn; i; i --)93 {94for(R j = Head[i]; j; j = Next[j])95 {96int x = date[j];97 q.push((node){v[x] + s[x], x});98 }99while(top) q.push((node){v[sta[top]], sta[top]}), -- top;//放回去100 LL y = m;101while(y && !q.empty())102 {103 node x = q.top();104if(!have[x.id])105 {106 q.pop(), ans[maxn] += x.v, x.v -= s[x.id];107 have[x.id] = 1, -- y, q.push(x);108 }109else110 {111 LL tmp = (last[x.id] - i) * d[x.id] + sum[x.id] - have[x.id];//获取这个菜还剩多少112if(tmp >= y) have[x.id] += y, ans[maxn] += x.v * y, y = 0;//还有就不⽤pop了113else114 {115 y -= tmp, have[x.id] += tmp, q.pop();116 ans[maxn] += x.v * tmp;117if(d[x.id]) sta[++top] = x.id;118 }119 }120 }121 can += m - y;122 }123 }124125void work()126 {127for(R i = 1; i <= k; i ++)128 printf("%lld\n", ans[read()]);129 }130131int main()132 {133// freopen("in.in", "r", stdin); 134 pre();135 build();//先获取最后⼀个的值136get();//再倒退出整个数组137 work();138// fclose(stdin);139return0;140 }View CodeProcessing math: 100%。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

示例: 【0,1,2】 【2,3,4】 【3,4,5,6
】【4,5,6,7】
【】 【2】 【2 ,1】 【2,1,4】 【2,1,4,6】
上述算法的指导思想是在某一区间中排 列越靠后的数对以后区间的影响越大, 即它在以后区间出现的可能性越大,但 未经严格数学证明

具体实现
由于pascal规定的集合类型只有[0..255], 因此在实现时不能使用集合作数据结构,用 数组直接保存也不行,因为在数组中查找数 据相当费时,注意到每个区间中的数大小不 超过10000,可用一个下标为[0..10000]的 布尔型数组标记该数是否出现过,从而解决 这一问题。
然后,我们通过多次尝试,可得出一个猜 想:
实际需要的覆盖边数完全等于我们求出的 下限∑[Pi/2](1<=i<=L)。
采用图的数据结构得出的算法为:
每次输出一条非桥的边,并从图中将边 的两顶点删去。
此算法的时间复杂度为O(n3)。 (寻找一条非桥边的复杂度为O(n2),寻找覆盖
边操作的复杂度为O(n))

证明
假设按照上述方法得到的解不是最优的,那 么必然存在某个工作j应当安排到处理的过程 中,却没有得到安排。假设我们要将该工作 安排进去,由于时间t[j]内都已经排满,就必 然需要将一个已安排的工作k与之替换,而 c[k]>=c[j],这样替换显然会增加罚款的数额 。因此,除上述安排方法以外的安排方法都 不会使罚款的数额减少,可得上述方法得到 的结果是最优的。
例题1 罚款问题
现有一台机器以及n项要完成的工作,该 机器每完成一项工作需要1的单位时间,而工 作i如果没有在t[i]的时间内完成,将会受到 c[i]的罚款。求怎样安排工作的顺序使完成 工作后总的罚款数最少。
分析
要使罚款最少,我们显然应尽量完成c[i]值较 大的工作。
此时,我们可以将工作按c[i]从大到小进行排 序,然后按照排好的顺序依次对工作进行安排 ,安排的规则为:使处理工作i的时间既在t[i] 之内,又尽量靠后;如果t[i]之内的时间都已经 排满,就放弃处理此项工作。
要满足用船最少的条件,就是需要尽量多的 两人共乘一条船,表现在图中就是要用最少 的边完成对所有顶点的覆盖。这就正好对应 了图论的典型问题:求最小边的覆盖。所用 的算法为“求任意图最大匹配”的算法。
分析
使用“求任意图最大匹配”的算法比较 复杂(要用到扩展交错树,对花的收缩等 等),效率也不是很高。因此,我们必须 寻找一个更简单高效的方法。
输出:最少元素数目。
示例输入: 4 36 24 02 47 输出: 4
分析
本题 “会场安排”问题十分相似,可以用同样 的贪心方法:按照所有区间的结束位置排序, 结束位置相同的项,开始位置小的项在前。从 区间1到区间n进行循环,对于当前区间,若集 合中的数不能覆盖它,则从区间末尾向前扫描 ,若当前数未在集合中出现,则将该数加入集 合,直至使集合能覆盖该区间为止。
例题2: INT(整数区间)
定义 一个整数区间[A,B],A﹤B,是一个从A 开始,至B结束的连续整数的集合。 任务是从文件中读取区间的个数及其对它们的 描述,找出满足下述条件的所含元素个数最 少的集合中元素的个数:对于每一个区间, 都至少有两个不同的整数属于该集合。
输入:
文本文件INT.IN的首行包括区间的数目N, 1≦N≦10000。接下来的N行,每行包括两个 整数A,B,被一空格隔开,0≦A≦B≦10000 ,它们是某一个区间的开始值和结束值。
贪心与分治
贪心方法
按照当前的状态,选择最好的决策,这就是贪 心法。在实际的应用中,人们往往不可能精确 计算出怎样才是最好的决策,只能凭借往常的 经验,保证每一步都是最好的选择。在解题的 过程中,这样的算法一般是比较容易想到并且 易于编程实现的。能够使用贪心算法解决的问 题,必然是每次都进行最优的选择,并且通过 证明其得到的最后结果也是最优的。
输出:仅一行,即最少分成的组数。 样例(STICK.IN) 5 8438239735 STICK.OUT 2
例题4:乘船问题(HNCOI)
有N个人需要乘船,而每船最多只能载 两人,且必须同名或同姓。求最少需要多 少条船。
问题分析
看到这道题,很多人都会想到图的数据结构 :将N个人看作无向图的N个点,凡同名或同 姓的人之间都连上边。
首先,由于图中任两个连通分量都是 相对独立的,也就是说任一条匹配边的 两顶点,都只属于同一个连通分量。因 此,我们可以对每个连通分量分别进行 处理,而不会影响最终的结果。
同时,我们还可以对需要船只s的下限进行估 计:
对于一个包含Pi个顶点的连通分量,其最小覆 盖边数显然为[Pi/2]。若图中共有L个连通分量 ,则s=∑[Pi/2](1<=i<=L)。
反之,如果不能证明每次进行最优选择后,最 终会得到最优的结果,就不能使用贪心算法。 其实,大部分的问题都是不能使用贪心算法的 ,
简单的例子:现有10元、7元、2元、1元四种 纸币,使用的张数不限,需要用这四种纸币凑 成p元钱,怎样用最少的张数达到此要求。
此题我们很容易就想到了贪心的算法,即每次 尽量选面值大的纸币。但是,在p=14时,贪 心算法的结果为14=10+2+2,而最优结果为 14=7+7,贪心显然是不对的。然而,如果我 们将其中的7元纸币换成5元纸币,贪心算法 却又是对的。这就需要我们用证明来判断了。
采用树结构解决
见文档
例题5:通讯保卫战
见文本
例题6:猜数游戏
猜数游戏是一个古老的智力游戏。一个 游戏者A首先想出一个数x(1 x n), 让另一个游戏者B来猜。现在由你扮演游
戏者B,用尽可能少的次数猜出x,并且 你所猜的数中大于x的数不能超过m个。
例题7:汤姆的游戏
在给定平面上N个图形(矩形或圆)以及M 个点后,请你求出每个点在多少个矩形 或圆内部(这里假设矩形的边都平行于坐 标轴)。
例题3:零件分组
某工厂生产一批棍状零件,每个零件都有一定的长度(Li)和重量(Wi)。 现在为了加工需要,要将它们分成若干组,使每一组的零件都能排成一个长 度和重量都不下降(若i<j,则Li<=Lj,Wi<=Wj)的序列。请问至少要分成 几组?
输入:第一行为一个整数N(N<=1000),表示零件的个数。第二行有N对正 整数,每对正整数表示这些零件的长度和重量,长度和重量均不超过10000 。
(N<=200000,M<=10000)
相关文档
最新文档