合并果子

原创 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根据上面的猜测就很好懂了

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

合并果子

合并果子 成绩 10 开启时间 2013年03月19日 星期二 14:40 折扣 0.8 折扣时间 2013年03月28日 星期...
  • y11201
  • y11201
  • 2013年06月18日 12:18
  • 3850

C++:泛型编程priority_queue(合并果子)

泛型编程priority_queue(合并果子)Time Limit(Common/Java):1000MS/3000MS Memory Limit:65536KByte Tota...
  • liangzhaoyang1
  • liangzhaoyang1
  • 2016年01月24日 13:22
  • 643

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

P1097合并果子 Accepted 标签:贪心NOIP提高组2004 描述 在一个果园里,多多已经将所有的果子打了下来,而且按...
  • qq_16542775
  • qq_16542775
  • 2015年05月12日 16:06
  • 1169

[NOIP2004] 合并果子-解题报告

[NOIP2004] 合并果子★☆ 输入文件:fruit.in 输出文件:fruit.out 简单对比 时间限制:1 s 内存限制:128 MB问题描述在一个果园里,多多已经将所有的...
  • Mu_Zhou233
  • Mu_Zhou233
  • 2016年10月13日 22:06
  • 555

Algorithm学习笔记 --- 合并果子

Algorithm学习笔记 --- 合并果子
  • u012965373
  • u012965373
  • 2014年05月06日 16:33
  • 1232

C++优先队列 合并果子

#include #include using namespace std; priority_queue que; int main(){ int n,x,tmp; scanf("%...
  • CM_yali
  • CM_yali
  • 2016年01月30日 12:08
  • 866

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

合并果子(fruit) 题目描述 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。  多多决定把所有的果子合成一堆。每一次合并,多多可以把两堆果子合并到一...
  • C20181220_xiang_m_y
  • C20181220_xiang_m_y
  • 2016年10月03日 14:19
  • 605

【竞赛题目对比】& 合并吧!石子合并 与 合并果子 &

这是两个不同的题目,来自两场不同的比赛,用了两种不同的算法,会出两个不同的答案。明明如此相像的题目,却又为何产生相差甚大的结果呢?不要着急,让我们缓缓揭开历史的纱幕,深度地去解析题目,除去笼罩着的迷雾...
  • Tiw_Air_Op1721
  • Tiw_Air_Op1721
  • 2017年08月20日 21:47
  • 528

【合并果子】的两种方法

哈夫曼树+堆 #include #include const int maxn=10000+10; using namespace std; int a[maxn]; int main(){ in...
  • cnyali
  • cnyali
  • 2017年06月04日 21:51
  • 272

【NOIP2004提高组】合并果子(贪心)

【问题描述】   在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。   每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子...
  • qq_35546304
  • qq_35546304
  • 2016年07月22日 11:10
  • 342
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:合并果子
举报原因:
原因补充:

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