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. amazeui学习笔记二(进阶开发5)--Web 组件开发规范Rules

    amazeui学习笔记二(进阶开发5)--Web 组件开发规范Rules 一.总结 1.见名知意:见那些class名字知意,见函数名知意,见文件名知意 例如(HISTORY.md Web 组件更新历史 ...

  2. Flask项目之手机端租房网站的实战开发(五)

    说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...

  3. 【博客之星】CSDN2013博客之星--分析和预测

    本文纯属个人见解,多有得罪啊! 具体结果,还是看最后CSDN给的结果吧! 昵称 名字 题材 质量 数量 知名度 预测 阳光岛主 杨刚 Python,Clojure,SAE 很高 346+ 很大 一定( ...

  4. hibernate 注解配置<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/X

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  5. 洛谷——P1021 邮票面值设计

    https://www.luogu.org/problem/show?pid=1021 题目描述 给定一个信封,最多只允许粘贴N张邮票,计算在给定K(N+K≤15)种邮票的情况下(假定所有的邮票数量都 ...

  6. 微信小程序踩坑- tabBar.list[3].selectedIconPath 大小超过 40kb

    重新启动微信小程序编辑器的时候遇到了这样的一个问题: tabBar.list[3].selectedIconPath 大小超过 40kb 微信小程序开发的过程之中总会出现这样或者那样的错误,需要我们耐 ...

  7. 《从零開始学Swift》学习笔记(Day 63)——Cocoa Touch设计模式及应用之单例模式

    原创文章,欢迎转载.转载请注明:关东升的博客 什么是设计模式.设计模式是在特定场景下对特定问题的解决方式.这些解决方式是经过重复论证和測试总结出来的. 实际上.除了软件设计,设计模式也被广泛应用于其它 ...

  8. vue指令概览

    原文 简书原文:https://www.jianshu.com/p/5fd47b7422fd 大纲 1.什么是vue指令 2.向指令中传入参数 3.指令中带入修饰符 4.指令的缩写 5.常见的vue指 ...

  9. 10.5 android输入系统_Reader线程_使用EventHub读取事件和核心类及配置文件_实验_分析

    4. Reader线程_使用EventHub读取事件 使用inotify监测/dev/input下文件的创建和删除 使用epoll监测有无数据上报 细节: a.fd1 = inotify_init(& ...

  10. 字符的输入和输出即:getchar和putchar

    #include <stdio.h> int main(int argc, const char * argv[]) { putchar(getchar());//这种方式就是输入一个字符 ...