《分治和倍增.docxVIP

  1. 1、本文档共8页,可阅读全部内容。
  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文档。上传文档
查看更多
《分治和倍增

分治和倍增DJ (纯手打,复制请标明出处与作者,谢谢!) 分治概念什么是分治? 字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。举个例子:快速排序,通过不断地将某一区间内的数分成比第一个数大的和比第个数小的两部分,如此便可将整个区间分成两小份,继续对每一个区间进行相同的操作,直到区间内只有两个数为止,此时便可以直接得到这个小区间的解,从而得出整个数列的解。这便是分治的基本思想的一个体现。分治主要分三步走:分、治、合。分:把问题分成n(一般为2)个子问题;治:解决子问题(继续分下去,或是规模小到一定程度后直接求解);合:将两个子问题合并,求出原问题的解。图片来源:百度百科例题逆序对逆序对概念:一个数列中,若存在ij且a[i]a[j],则a[i]、a[j]为一组逆序对。我们的问题是:给定一组数列,求其中所有逆序对个数。朴素算法:很容易,两个指针一路遍历,找到符合定义的i、就ans+=1,找完为止。两个for即可。优点:编程难度极小;缺点:复杂度挺高,有O(n2)。O(n2)无法满足联赛随随便便就玩100000的数据,我们需要一种更优的算法。怎么办?无序数列挺烦的,假如我们有一种神奇的算法把数列两半分别有序化,可以在O(n)时间内算出它的逆序对并将其整体排序吗?答案是肯定的。看到两组有序数列合并,大家一定想到了归并排序。这简单地用两个指针O(n)就能合并两个有序数列的方法在这种情况下可以轻易解决第二问。我们可以在合并时动点手脚,让它顺便记录下前后的逆序对,加入ans中。动什么手脚呢?不难发现,当前半段的数a[i]比后半段的数a[j]大时,前半段在i后面所有的数均与a[j]组成一对逆序对,则把后面所有数的个数加入ans,其他按照归并排序按部就班地进行就行了。那么无序呢?分治!分治算法:将整个数列分成两份,一直分,直到规模降为1或2,直接得出此区间内的逆序对,再保证这个小区间内数列有序,然后对上一级子问题归并排序顺便找逆序对,最后得到整个问题的解。复杂度:O(n log n)。具体例子见PPT。平面最近点对在一个平面内给出若干个点,求其中最近的两个点的距离。朴素算法:万能的两个for,O(n2)。O(n2)是无法满足的。我们需要更快更好的方法!先看看一维。分治法求一维最近点对,怎么破? 显然是分成两段,分别求出这两段中最近距离,再算最接近分界线的两个点的距离与左右两边最近距离比较得到最终答案。不过,这两段是从区间中位数分,还是从什么地方分更高效呢?横坐标的中位数!那么,拓展到二维呢?类似的,我们可以把整个平面根据点的横坐标的中位数分成两个半平面,在求出每个半平面的最近点对后,再考虑分界线附近这些点的距离,在其中找到更优解后更新ans的值。重点来了:如何算分界线附近这些点的距离呢?两两暴搜?显然不必。根据已经处理好的两个半平面,我们可以发现:同侧所有点之间的距离必定不小于当前最优解,设它为m。则我们只需遍历左侧的点,再分别找与之靠近的右侧点就行了。这个“靠近”是靠得多近呢?从数学的角度,显然是以此点位圆心,m为半径的圆内,若有点,更新;否则不更。但你如何判断右侧的点在这个圆内呢?遍历=_=……于是问题差不多又回到了原点。判圆太麻烦了,肯定不行。我们知道了所有点的横纵坐标,不如干脆直接扩大圆,把圆扩大成一个矩形:与这个点纵坐标之差不超过m的点都在这个矩形内。也许有人会问:你本来好好一个圆,扩成一个矩形不是增加了点,增大了复杂度吗?事实上,这个矩形内的点没有大家想的那么多:最多6个。不信?请读者拿出纸笔,咱们来证明一下:画一个点,在它右边画一条竖直线作为分界线,再右边一些画一条竖直线作为右区间界线。从某个点开始,分别向上、向下画一条长为m的线段,分别在线段的尽头画分界线的垂线,与右边的小区间界线、中间的分界线组成一个2m*m的矩形;在长上,画出两条三等分线,将矩形分成3个2/3m*m的小矩形,再在宽上画条中线,将整个矩形分成6个2/3m*1/2m的小矩形;对于每个矩形,假设其内部有两个点,则这两个点的距离小于等于对角线的长度。对角线由勾股定理算得为5/6mm,所以这两个点的距离会小于m。嗯?不对啊!m明明是每个半平面内最近距离的最小值,怎么还会在单独一个半平面内有距离小于m的点对呢?这不EA!矛盾了!所以,每个矩形内最多只有1个点,整个矩形内最多只有6个点。有了这个定理做支撑,我们可以确保此算法的快捷了!我们可以将这些点按y排序,再遍历左边的点,对于每个点去找右边y与之相差不大于m的点,一一判断更新m值。不过,我们只需更新m,不必进一步缩小区间。(想想为什么?)于是我们便得到了整个问题的解。二分答案概念有的时候,我

文档评论(0)

tiantiande + 关注
实名认证
文档贡献者

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

1亿VIP精品文档

相关文档