Time Limit: 1 second

Memory Limit: 50 MB

【问题描述】

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

【输入】

共2行;

    第一行是一个整数n(1<=n<=10000),表示果子的种类数。

    第二行是第二行包含n个整数,用空格分隔,第i个整数ai(1<=ai<=20000)是第i种果子的数目。

【输出】

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

【输入样例】

    3
    1 2 9

【输出样例】

    15

【 数据规模】

30%的数据满足:n<=1000

    50%的数据满足:n<=5000

100%的数据满足:n<=10000

【题解】

法一:将所有的果子数目快排一遍,然后合并前两个。再把合并的放到序列中(插入排序)

重复此步骤n-1次即可。

法二:用一个小根堆来维护整个序列的最小值。建堆的话,一开始要从倒数第二层开始建。然后往下调整。这样可以保证建堆是正确的。然后依然是重复n-1次操作。每次操作:先取出dui[1]即堆中的最小值。然后把堆尾的元素放到1位置。然后堆的大小递减。然后从1开始往下进行调整。维护堆。取出来的第一个数字为a,然后同样的,取出经过维护之后的堆中的第一个元素即最小值,设为b,然后堆的大小递减。同样从第一个元素开始往下调整堆。然后c=a+b,再把堆的大小递增,把c放到堆的最后面。然后从堆的最后一个位置往上进行调整。获取这个新插入的元素它最后的位置。然后从那个位置再往下进行调整即可。然后重复此步骤n-1次即可。

【代码】

#include <cstdio>

int n,dui[20001],size,pos,sum = 0;

void down_tiaozheng(int p) //往下调整
{
int x =dui[p]; //先记录要被调整的数字的大小。
int i = p,j = p*2; //p*2就表示其左儿子
while (j <= size) //如果没有超过树的范围
{
if (j < size && dui[j+1] < dui[j]) //获取它们之中较小的那个数。这样经过调整这个dui[j]
j++; //可能会往上交换。也能满足每个节点都比儿子节点小了。
if (x > dui[j]) //如果要进行交换 则交换
{
dui[i] = dui[j];
i = j;
j = i*2;
} //不用交换就可以结束了。
else
break;
}
dui[i] = x; //把x放到某个位置;
} void up_tiaozheng(int p) //往上调整
{
int x = dui[p]; //记录下要调整的数字大小
int i = p,j = p/2; //除2表示往上进行调整 即其父亲节点。
while (j > 0) //如果没有超过树的范围。则继续
{
if (dui[j] > x) //父节点只有一个。所以不用再判断了。
{
dui[i] = dui[j];//进行调整
i = j;
j = j/2;
}
else //如果不会出现冲突了
break; //就结束调整的过程。
}
dui[i] = x; //把它调整到i位置
pos = i; //然后记录它调整到了哪个位置。方便之后再往下调整。
} void input_data()
{
scanf("%d",&n);
for (int i = 1;i <= n;i++)
scanf("%d",&dui[i]);
size = n;
} void get_ans()
{
for (int i = (n/2);i>=1;i--) //输入数据完之后要进行建堆的操作,从倒数第二层开始调整以建堆
down_tiaozheng(i);
for (int i = 1;i <= n-1;i++)
{
int a = dui[1]; //取出两次堆中的第一个元素。然后调整两次堆。(取完就调整)
dui[1] = dui[size];
size--;
down_tiaozheng(1);
int b = dui[1];
dui[1] = dui[size];
size--;
down_tiaozheng(1);
int c = a+b;
sum+=c;
size++;
dui[size] = c; //把累加的c加到堆中
up_tiaozheng(size); //先往上调整。再往下调整。
down_tiaozheng(pos);
}
} void output_ans()
{
printf("%d\n",sum);
} int main()
{
//freopen("F:\\rush.txt","r",stdin);
input_data();
get_ans();
output_ans();
return 0;
}

【9602】&&【b402】合并果子的更多相关文章

  1. 【noip 2004】 合并果子

    noip2016结束后的第一份代码--优先队列的练习 合并果子 原题在这里 #include <iostream> #include <queue> #include < ...

  2. 合并果子 2004年NOIP全国联赛普及组

    时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆 ...

  3. NOIP2004合并果子

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

  4. codevs 1063 合并果子//优先队列

    1063 合并果子 2004年NOIP全国联赛普及组  时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石    题目描述 Description 在一个果园里,多多已经将所有的果 ...

  5. [KOJ6024]合并果子·改(强化版)

    [COJ6024]合并果子·改(强化版) 试题描述 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多把这些果子堆排成一排,然后所有的果子合成一堆.    每一次合并 ...

  6. [KOJ6023]合并果子·改

    [COJ6023]合并果子·改 试题描述 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多把这些果子堆排成一排,然后所有的果子合成一堆.    每一次合并,多多可以 ...

  7. [KOJ0574NOIP200406合并果子]

    [COJ0574NOIP200406合并果子] 试题描述 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合成一堆.    每一次合并,多多可以把两 ...

  8. NOIP提高组2004 合并果子题解

    NOIP提高组2004 合并果子题解 描述:在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合成一堆. 每一次合并,多多可以把两堆果子合并到一起,消 ...

  9. 【NOIP合并果子】uva 10954 add all【贪心】——yhx

    Yup!! The problem name reects your task; just add a set of numbers. But you may feel yourselvesconde ...

随机推荐

  1. Java Web学习总结(15)——JSP指令

    一.JSP指令简介 JSP指令(directive)是为JSP引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分. 在JSP 2.0规范中共定义了三个指令: pa ...

  2. GCJ 2008 Round 1A Minimum Scalar Product

    https://code.google.com/codejam/contest/32016/dashboard 题目大意: GCJ(google code jam)上的水题.下周二有比赛,来熟悉熟悉. ...

  3. 原生js大总结一

    001.浅谈堆和栈的理解?   js变量存储有栈存储和堆存储,基本数据类型的变量存储在栈中,引用数据类型的变量存储在堆中 引用类型数据的地址也存在栈中   当访问基础类型变量时,直接从栈中取值.当访问 ...

  4. Visual studio编译器窗体重置

    针对vs2003: 第一种方法 在"工具"->"选项"对话框里面:  在"选项"以下的"常规"有个"重置 ...

  5. js课程 4-11 表格如何实现隔行换色

    js课程 4-11 表格如何实现隔行换色 一.总结 一句话总结:表格奇数行和偶数行判断,赋予不同的样式. 1.表格如何隔行换色? 表格奇数行和偶数行判断,赋予不同的样式. 21 <script& ...

  6. netty reactor线程模型分析

    netty4线程模型 ServerBootstrap http示例 // Configure the server. EventLoopGroup bossGroup = new EpollEvent ...

  7. html5 10大html5前端框架

    Bootstrap 首先说 Bootstrap,估计你也猜到会先说或者一定会有这个( 呵呵了 ),这是说明它的强大之处,拥有框架一壁江山的势气.自己刚入道的时候本着代码任何一个字母都得自己敲出来挡我者 ...

  8. [RxJS] Implement pause and resume feature correctly through RxJS

    Eventually you will feel the need for pausing the observation of an Observable and resuming it later ...

  9. ping localhost 没反应解决方式

    今天在搭建导师公司的spark的集群的时候须要有一台机器须要ssh 到自己.可是运行以下两条命令后发现没有反应 ping localhost ping 127.0.0.1 之后问了下别人,发现是/et ...

  10. 初步安装git使用命令配置电脑中的git关联的账户

    原文地址 https://www.jianshu.com/p/39684a3ad4fa 出现问题 当我们初步使用git的时候,会报一些出乎预料的错误,比如:报错:fatal: unable to au ...