1. 1、本文档共27页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
p1011

问题描述 Sticks Description George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now he wants to return sticks to the original state, but he forgot how many sticks he had originally and how long they were originally. 解题要求 1. Time Limit, Memory Limit 2. Input 3.Output Time Limit:5S? Memory Limit:10000K Input The input file contains blocks of 2 lines. The first line contains the number of sticks parts after cutting. The second line contains the lengths of those parts separated by the space. The last line of the file contains zero. Output The output file contains the smallest possible length of original sticks, one per line. 基本思路 从小到大,逐个尝试可能的长度。 设已知的n根短棍的长度分别是: l1,l2,…,ln 现在的问题就是:要判断这n根短棍是否可以组成m根长为length的长棍。 这题和Dividing(1014)那题很像,从题意上可以把Dividing看成是此题的简化版本。然而仔细分析这两题有很大不同,因此解法也是大相径庭的。 Dividing那题的数据总量可以达到20000,直接的深度优先搜索是很难奏效的,所以我们的想法是如何有效的减少数据总量。 而对于此题来说,虽然我不知道实际测试数据的最大的数据量(sticks的总数)是多少,但是我只用了一个长为100的数组保存也没有越界。说明总的数据量不超过100(注:要解这题要我觉得要使用深度优先搜索,对于深度优先搜索来说100已经是很大的数了)。 具体思路 对于这个问题,可以有2种不同的解决方法: 1.逐个使用l1,l2,…ln来填充长棍。 2.逐个填充长棍,填完一根长棍,再填下一根。 无论是哪一种解题思路,我们都可以“感觉到”如果有如下的关系成立 l1=l2=…=ln 那么对于解题是十分有利的。事实也是如此,在此种情况下将会比较高效的排除不可能的情况。 此题的实际测试结果也是如此,如果读入数据后没有排序,我所见过每种算法都会超时。 第一种思路的程序框架 bool solve(k){//填第k根短棍 for(i=0;im;i++){ if(lk+第i根长棍已填的部分=length){ 把lk填入第i根长棍; if(solve(k+1)==true)return true; 把lk从第i根长棍中取出; } return false; } 这个想法很简单,但是效率也是低得可怕,因此我们得想一些方法来优化。 以下是我所加的第一个优化: 有若干个长棍都没有被填充过,如果现在将li填入其中一个作过尝试,就不用再填到别的长棍中作尝试了。 这样可以减少很多重复的尝试。比如l1永远只会被填入第一根长棍内。 我的第二个优化如下: 从这n根短棍中取出若干接成一根长棍(不是题目要求中的长棍),得到的长棍的长度只有有限多种。这就是说,有些长度是不能由若干根短棍组成的。 我们可以将不能组成的长度记录下来。 在每一次填充之前先检查一下,当前想填的长棍还没有填充的部分是否是可能由若干短棍组成。若不行,则在此种情况下无论怎样也不可能完成填充。这时我们就可以不用搜索,而可以直接回溯了! 我的第三个优化: 假设某一根长棍还没有填满的部分的长是l,并且在还没有使用的短棍中恰好有一根的长度也是l,不妨设是ls。那么我们可以直接把ls填到此根长棍上。 这个想法不是很明显,不过稍微思考一下就可以明白。 但现在的情况还是: Time Limit Exceed 搞笑的结果 我实在是没辙了,就在程序中加了几段计时的语句: 如果在一定时间内不能否定当前的长度是正确答案,就认为这就是正确答案。 这样将程序提交,竟然通过了! 以上是我的做法,虽然通过了所有的测试数据,但

文档评论(0)

mv2323 + 关注
实名认证
内容提供者

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

1亿VIP精品文档

相关文档