NOIP基础算法——贪心和分治pascal.pptVIP

  1. 1、本文档共98页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
NOIP基础算法——分治与贪心 巴蜀中学 黄新军 第五部分 分治策略 一、分治思想 分治(divide-and-conquer)就是“分而治之”的意思,其实质就是将原问题分成n个规模较小而结构与原问题相似的子问题;然后递归地解这些子问题,最后合并其结果就得到原问题的解。 二、分治法的适用条件 能使用分治法解决的问题,它们一般具备以下几个特征: ①该问题可以分解成若干相互独立、规模较小的相同子问题; ②子问题缩小到一定的程度就能轻易得到解; ③子问题的解合并后,能得到原问题的解; 分治法在信息学竞赛中应用非常广泛,使用分治策略能生成一些常用的算法和数据结构,如快排、最优二叉树、线段树等;还可以直接使用分治策略,解决一些规模很大、无法直接下手的问题。 三、分治的三步骤 ①分解:将要解决的问题分解成若干个规模较小的同类子问题; ②解决:当子问题划分得足够小时,求解出子问题的解。 ③合并:将子问题的解逐层合并成原问题的解。 由分治法所得到的子问题与原问题具有相同的类型。如果得到的子问题相对来说还太大,则可反复使用分治策略将这些子问题分成更小的同类型子问题,直至产生出不用进一步细分就可求解的子问题。分治求解可用一个递归过程来表示。 要使分治算法效率高,关键在于如何分割?一般地,出于一种平衡原则,总是把大问题分成K个规模尽可能相等的子问题,但也有例外,如求表的最大最小元问题的算法,当n=6时,等分定量成两个规模为3的子表L1和L2不是最佳分割。一般来讲,都是2分为主。 四、分治的框架结构 五、分治的典型应用 1、求最大值和最小值 2、非线性方程求根 3、二分查找 4、归并排序 5、快速幂 6、求解线性递推关系 7、棋盘覆盖问题 8、循环日程表问题 9、寻找最近点对 1、求最大值和最小值 例题1:给n个实数,求它们之中最大值和最小值,要求比较次数尽量小。 用分治法解决这个问题就是把集合a分成a1,a2两个子集,每个子集有n/2个元素,应用递归结构找出两个子集的最大元和最小元,比较得到的两个最大元和最小元即可得到整个集合a中的最大元和最小元。 划分:把n个数均分为两半。即:划分点为d=(r1+r2)/2,两个区间为[r1,d]和[d+1,r2]。 递归求解:求左半的最小值min1 和最大值max1以及右半最小值min2和最大值max2。 合并:所有数的最大值为maxx,最小值为minn。 2、非线性方程求根 分析 如果精确到小数点后两位,可用简单枚举法:将x从-100.00 到100.00(步长0.01)逐一枚举,得到20000个 f(x),取其值与0最接近的三个f(x),对应的x即为答案。而题目已改成精度为小数点后4位,枚举算法时间复杂度将达不到要求。 直接使用求根公式,极为复杂。加上本题的提示给我们以启迪:采用二分法逐渐缩小根的范围,从而得到根的某精度的数值 分析 A.当已知区间(a,b)内有一个根时; 用二分法求根,若区间(a,b)内有根,则必有f(a)*f(b)0。重复执行如下的过程: (1).若a+0.0001b或f((a+b)/2)=0,则可确定根为(a+b)/2并退出过程; (2).若f(a)*f((a+b)/2)0,则由题目给出的定理可知根在区间(a,(a+b)/2)中,故对区间重复该过程; (3).若f(a)*f((a+b)/2)0,则必然有f((a+b)/2)*f(b)0,根在((a+b)/2,b)中,对此区间重复该过程。 执行完毕,就可以得到精确到0.0001的根。 分析 B、求方程的所有三个实根 所有的根的范围都在-100至100之间,且根与根之差的绝对值=1。因此可知:在[-100,-99]、[-99,-98]、……、[99,100]、[100,100]这201个区间内,每个区间内至多只能有一个根。即:除区间[100,100]外,其余区间[a,a+1],只有当f(a)=0或f(a)·f(a+1)0时,方程在此区间内才有解。若f(a)=0 ,解即为a;若f(a)·f(a+1)0 ,则可以利用A中所述的二分法迅速出找出解。如此可求出方程的所有的解。 核心参考代码 3、归并排序 归并排序的基本思想:归并排序充分应用分治算法的策略,通过二分的思想,将n个数最终分成n个单独的有序数列,每个数列中仅有一个数字;再将相邻的两列数据合并成一个有序数列;再重复上面的合并操作,直到合成一个有序数列。按照分治三步法来说, 归并过程为: (1)划分:把序列分成元素个数相等的两半; (2)递归求解:把两半分别排序; (3)合并:把两个有序表合成一个有序表; 分析 显然,前两部分是很容易完成的,关键在于如何把两个有序表合成一个。每次只需要把两个序列中当前的最小元素加以比较,删除较小元素并加入合并后的新表。 核心参考代

文档评论(0)

精华文档888 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档