埃及分数 题解.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
埃及分数 题解

埃及分数 题解 [初步分析] 埃及分数问题属于数论的一个分支“丢番图方程”,现在的研究已经比较深入了, 不过仍有 很多问题尚未解决。这个题目虽然看起来很简单,但是我们几乎不可能想到一个纯 理论性的 方法解决,搜索势在必行。 最基本的搜索方式有深度优先和广度优先。这道题目用深度优先很难出解,因为我 们无法预料 找到的地一个解的深度,因此我们考虑有广度优先方法。 暂且不考虑广度优先是否最好,我们先来考虑算法的具体实现。 1.节点类型: 是一个K元组(a1,a2,...ak), 代表当前解中的分母a1,a2..ak 我们暂时令k=6,也就是最多保存6个分母(如果觉得不够自己增加k的值) 2.节点扩展: 按照a1a2a3..ak的顺序扩展。(这个是通常做法,大家都知道吧) 扩展第k层节点的时候,最笨的方法,就是从a[k-1]+1开始枚举a[k],一直到预先确 定的最大值。 但是这个最大值怎么确定呢? 直观的讲,a[k]总不能太大,因为如果a[k]太大,1/a[k]就很小,1/a[k+1] .. 1/a[k+2].. 就更小,那么 可能加了好多项,还不够a/b.. !@#$!@#$,哎,都怪1/a[k]太小了,没有起到什么作用。 例如: 例如已经扩展到 19/45=1/5+???? 那么如果第二项是1/100, 那么由于19/45-1/5=2/9=0.22222... 那么接下来至少要0.2222/(1/100)=22项加起来才足够2/9, 所以继续扩展下去至少 还要扩展22项(天哪!) 加起来才差不多足够a/b。这么多项,不大可能是最优解吧! [确定搜索算法] 好了,刚才的分析其实是在引导我们进行剪枝,但是广度优先搜索停止于第一个解 的发现, 找到第一个解之前谁也不感贸然把22项那个“大解”扔掉 - 万一它真的是最优解 呢? 我们希望在预测深度方面剪枝,但是广度优先搜索并不能让我们大胆的剪,这样的 情形,我们通常有三种 解决方法: 1.分支定界 如果还能够给节点找到上界,相当于有了较优解,那么我们可以放心的对很多“大 得荒唐”的节点放心的剪枝。 但是本题的上界不大容易给出(至少我现在的知识只知道一些特殊情况的上界), 所以在本题中,这个方法并 不实用 2.启发式搜索 既然22不大可能是最优解,我们不扔它,不过也不急着扩展,总可以了吧。理论比 较完???的启发式搜索是A*, 不过本题用A*实在没多大必要。 3.迭代加深搜索(Iterative Deepening) 迭代加深搜索对于多数初学者来说是个陌生的名词,不过其实原理非常简单: 也就是说: for depth:=1 to maxdepth do if search then begin writeln(Best=,depth); break; end; 明白了吗? 你一定明白了,不过可能会想: 这样不是重复搜索了好多东西吗? 是的,是重复搜索,但是它的好处在于: 1.空间开销小 因为每个深度下实际上是一个深度优先搜索,不过深度有限制,而DFS的空间消耗 小是众所周知的。 本题不是很明显,不过在节点复杂的题目里,用BFS和A*空间会远远不足的。 2.编程方便,利于调试 利用递归,我们甚至不需要自己建栈,而BFS用到的队列和A*用到的堆,二分检索 树等是比较麻烦的。 3.时间效率不低 虽然重复搜索,但是大家不难理解,前一次搜索跟后一次相不是微不足到的。这一 点我在我的冬令营论文 中有详细叙述 4.利于深度剪枝 在这道题目中,这是迭代加深搜索最大的优势。 比如当前深度是3,那么那个22肯定就不要了。而如果最优解是4,肯定在depth=4的 时候就能得到最优解 (从而立刻结束搜索),也就是说,22个那个东西每次都没用,这和我们主观的剪 枝动机是一致的。 最后,对于不熟悉搜索的程序编制的朋友,这里我写出PASCAL和C各一个程序,我 尽量写得easy to read, 希望大家有所帮助。 [关于代码的改进] 大家注意我的枚举部分的实现。 我先把枚举的边界s和t求出来再枚举,而不是每次判断时候需要剪枝,这样的代码 要快得多。 s:=b div a; {再小递归以后就是负数了:-P} if sd[k-1]+1 then s:=d[k-1]+1; {搜索顺序} t:=(depth-k+1)*b div a; {根据当前深度定下的最大值} if tmaxlongint div b then t:=maxlongint div b; if found and (t=answer[depth]) then t:=answer[depth]-1; 再是: for i:=s to t do ... 另外,最容易出错的一点是,递归的时候,求得的新分数必须约分,否则可能出现 算术

文档评论(0)

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

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

1亿VIP精品文档

相关文档