网站大量收购闲置独家精品文档,联系QQ:2885784924

ACM经典C++题目:Gone Fishing算法详解及源代码【精品】.docVIP

ACM经典C++题目:Gone Fishing算法详解及源代码【精品】.doc

  1. 1、本文档共9页,可阅读全部内容。
  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文档。上传文档
查看更多
Gone Fishing算法详解及源码 这道题其实难在读题上,因为这道题的细节太多,往往容易搞混,造成WA的情况,所以,学好英语还是有作用的。 解此题的主要方法是枚举+贪心。刚开始的时候还没想到一个好方法,因为当前鱼最多的池塘是变化的,而题目所给描述里面的钓鱼又是有顺序的,即:John starts at lake 1, but he can finish at any lake he wants. He can only travel from one lake to the next one, but he does not have to stop at any lake unless he wishes to.所以,不可能在池塘中间瞬移,所以贪心貌似不能用。 但转念一想,瞬移还是有可能的,当确定了结束池塘ep(endpond)之后(结束池塘由1枚举到n),我们便可以把从1到ep的交通费用从h中减去,然后用剩下的时间贪心即可。因为在分析问题时,对于一个池塘,John在它上面什么时候钓鱼并不重要,所以可以先把John看成很聪明的人,然后假设他已经知道了在确定了结束池塘后,在每个池塘花多少时间使收益最大(实际上John是在贪心之后才知道的),这时我们就可以先减去交通费用,然后在1~ep的池塘中找现在的最大的即可。 这道题还比较容易WA,但最容易WA的地方还是全零的情况。 法2,没问题: 简单题 直接枚举结束湖泊+贪心选择就可以了 为什么可以贪心?(反正你要取的是最优解 你可以假定自己知道最优解 一路走过去的路上就直接取最优解就可以了) 因为集训的时候这个题目莫名WA 故再A一遍 以解心头之恨! using namespace std; 不能用time G++ CE多次 faint Gone Fishing Solution: // by oyjpArt 给定由n个整数(包含负整数)组成的序列a1,a2,...,an,求该序列子段和的最大值。当所有整数均为负值时定义其最大子段和为0。 依此定义,所求的最优值为: 例如,当(a1,a2, a3, a4, a5,a6)=(-2,11,-4,13,-5,-2)时,最大子段和为: 一个简单算法: int MaxSum(int n, a, besti, bestj) { int sum=0; for(i=1;i=n;i++) for(j=1;j=n;j++){ int thissum=0; for(k=i;k=j;k++) thissum+=a[k]; if(thissumsum){ sum=thissum; besti=i; bestj=j;} } return sum; } 算法有3重循环,复杂性为O(n3)。 由于有: 算法可作如下改进: int MaxSum(int n, a, besti, bestj) { int sum=0; for(i=1;i=n;i++){ int thissum=0; for(j=i;j=n;j++){ thissum+=a[j]; if(thissumsum){ sum=thissum; besti=i; bestj=j; } } } } 改进后的算法复杂性为O(n2) 。 从问题的解的结构可以看出,它适合于用分治策略求解: 如果将所给的序列a[1:n]分为长度相等的两段a[1:n/2]和a[n/2+1:n],分别求出这两段的最大子段和,则a[1:n]的最大子段和有三种情形: a[1:n]的最大子段和与a[1:n/2]的最大子段和相同; a[1:n]的最大子段和与a[n/2+1:n]的最大子段和相同; a[1:n]的最大子段和为下面的形式。 A、B这两种情形可递归求得。对于情形C,容易看出,a[n/2]与a[n/2+1]在最优子序列中。因此,我们可以在a[1:n/2]和a[n/2+1:n]中分别计算出如下的s1和s2。则s1+s2即为出现情形C时的最优值。 从而设计出下面所示的分治算法。 1

文档评论(0)

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

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

1亿VIP精品文档

相关文档