合并果子

原创 2016年08月30日 12:01:41

为了防止抄袭代码,本人只供应伪代码

1.题目:

合并果子

成绩 10 开启时间 2013年03月19日 星期二 14:40
折扣 0.8 折扣时间 2013年03月28日 星期四 14:40
允许迟交 关闭时间 2013年06月30日 星期日 14:40

在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。

     例如有3种果子,数目依次为1,2,9。可以先将 1、2堆合并,新堆数目为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为 12。所以多多总共耗费体力=3+12=15。可以证明15为最小的体力耗费值。

【输入】包括两行,第一行是一个整数n(1≤n≤10000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1≤ai≤20000)是第i种果子的数目。

【输出】包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输入数据保证这个值小于231。

  测试输入关于“测试输入”的帮助 期待的输出关于“期待的输出”的帮助 时间限制关于“时间限制”的帮助 内存限制关于“内存限制”的帮助 额外进程关于“{$a} 个额外进程”的帮助
测试用例 1 以文本方式显示
  1. 3↵
  2. 1 2 9↵
以文本方式显示
  1. 15↵
1秒 64M 0

2.思路

1.错误的思路:

有的人在网上可能找到了一些参考的思路,比如贪心+快排,好吧,包括我在内,但是在这里我非常想要给各位提个醒,这道题的输入的数据有些强,快排的话我们每次都要对顺序表进行更新,所以说,虽然有着O(n*lgn)的强大的速度和效率,但是很抱歉,这道题会超时

在这里我们每次都要对数组进行实时的维护,时间复杂度计算有些麻烦,大致上应该是

O()=SUM(lg1+2*lg2+3*lg3+...n*lgn)很抱歉,学艺不精,大致应该是O(n*n*lgn)(如果错了,欢迎批评指正),所以说,这道题在输入数据过于强大的时候,超时是一定会发生的事情

2.正确的思路:

这道题我们正确的思路应该是优先队列进行处理

首先我们先来了解一下什么是优先队列,优先队列是一种高级数据结构,我们队队列中的每个数据成员都附加上一个优先级,每一次,我们都是按照优先级对队列的成员进行排序,优先级高的成员先出队列

在这里,我们可以采用两种实现方式

1.二叉堆实现优先队列

2.链表模拟优先队列

对于二叉堆的优先队列的话,我们采用对的额性质,维护最小堆,每次对堆进行递减维护

用链表的话,我们这里的思路有些相对于优化快排+贪心的策略,我的思路是每次合并完之后,我们队队列进行插入操作,这样比整体快排要好一些,但是因为数据强大,本人尝试,本体用链表插入的思路非常的慢,刚刚好AC,所以大家最好不要尝试,对于二叉堆的思路我会原因我的博客作为讲解

3.代码讲解:

优先队列实现过于简单,我们不作讲解

在这里我们着重讲解二叉堆

siftdown(i)
      t 
      flag <- 0
      while(i*2<=n and flag = 0)
           if heap[i*2]<heap[i] t <- i*2
           else t <- i
           if i*2+1 <=n and heap[i*2+1]<heap[t] t <- i*2+1
           if t != i 
                swap(i,t)
                i=t;
           else flag = 1;

在这里,我们会用到二叉树的一个性质就是,在顺序表中进行二叉树的存储的话,根节点的编号如果是n,那么做儿子存在的话编号就是2*n,右儿子存在的话就是2*n+1

建堆操作:

buildheap(i)
     for i = n/2 downto1
          siftdown(i)

这里的n/2根据上面的猜测就很好懂了

版权声明:本文为博主原创文章,未经博主允许不得转载。

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

【市选模拟题】合并果子

这是标准合并果子的改版,一次最多合并K堆。殊不知此题有大坑……点进来看吧...

Vijos-P1097-合并果子(简单贪心 && 优先队列 && c++)

P1097合并果子 Accepted 标签:贪心NOIP提高组2004 描述 在一个果园里,多多已经将所有的果子打了下来,而且按...

果子合并(ACM/ICPC训练题)

  • 2011年12月20日 10:17
  • 1.04MB
  • 下载

合并果子源代码

  • 2015年09月13日 10:46
  • 2.44MB
  • 下载

[NOIP2004]合并果子 T2 数据结构 简单贪心

在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有...

合并果子源程序

  • 2014年11月27日 20:48
  • 930B
  • 下载

树-堆结构练习——合并果子之哈夫曼树

Problem Description 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。 每一次合并,多多可以把两堆果子合并到一起,...
  • minose
  • minose
  • 2017年06月03日 19:51
  • 107

树-堆结构练习——合并果子之哈夫曼树

题目描述  在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。 每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重...

【二叉树】 堆应用:合并果子

合并果子(fruit) 题目描述 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。  多多决定把所有的果子合成一堆。每一次合并,多多可以把两堆果子合并到一...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:合并果子
举报原因:
原因补充:

(最多只允许输入30个字)