洛谷P1090 合并果子

题目描述

在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。

每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。

因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。

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

输入输出格式

输入格式:

输入文件fruit.in包括两行,第一行是一个整数n(1<=n<=10000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1<=ai<=20000)是第i种果子的数目。

输出格式:

输出文件fruit.out包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输入数据保证这个值小于2^31。

输入输出样例

输入样例#1:

3
1 2 9

输出样例#1:

15

说明

对于30%的数据,保证有n<=1000:

对于50%的数据,保证有n<=5000;

对于全部的数据,保证有n<=10000。

屠龙宝刀点击就送1

屠龙宝刀点击就送2

priority做法 35ms 383B

#include <algorithm>
#include <iostream>
#include <queue>

using namespace std;

priority_queue<int,vector<int>,greater<int> >q;
int n,a,h=0;
int main()
{
    cin>>n;
    while(n--)
    {
        cin>>a;
        q.push(a);
    }
    while(q.size()!=1)
    {
        int ans=0;
        int r=q.top() ;
        q.pop();
        ans+=r;
        r=q.top() ;
        q.pop();
        ans+=r;
        q.push(ans);
        h+=ans;
    }
    cout<<h;
}

堆做法 18ms 785B

#include <algorithm>
#include <cstdio>

using namespace std;

int n,i,j,a,size,heap[10000*4+1];
void heap_push(int n)
{
    heap[++size]=n;
    int pos=size;
    while(pos>1)
    {
        int next=pos/2;
        if(heap[next]<heap[pos]) break;
        swap(heap[next],heap[pos]);
        pos=next;
    }
}

void heap_pop()
{
    heap[1]=heap[size--];
    int pos=1;
    while(pos*2<=size)
    {
        int next=pos*2;
        if(heap[next]>heap[next+1])
        next++;
        if(heap[next]>=heap[pos]) break;
        swap(heap[next],heap[pos]);
        pos=next;
    }
}
int main()
{
    scanf("%d",&n);
    for(i=1;i<=n;++i)
    {
        scanf("%d",&a);
        heap_push(a);
    }
    int ans=0;
    while(size>1)
    {
        int h=0;
        h+=heap[1];
        heap_pop();
        h+=heap[1];
        heap_pop();
        heap_push(h);
        ans+=h;
    }
    printf("%d",ans);
    return 0;
}

时间: 2024-07-30 13:46:42

洛谷P1090 合并果子的相关文章

[NOIP2004] 提高组 洛谷P1090 合并果子

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

洛谷 1090合并果子

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

P1090 合并果子

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

P1090 合并果子(哈弗曼树)

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

【洛谷】P1090 合并果子

这道题很经典 . 考点:二叉堆,贪心 我写了两个版本.顺便复习一下手工堆. 系统堆版: #include<bits/stdc++.h> using namespace std; priority_queue <int> q; int main() { int n; long long ans = 0; scanf("%d",&n); for (int i = 1 , x ; i <= n ; i ++) { scanf("%d"

[题解]洛谷比赛『期末考后的休闲比赛2』

[前言] 这场比赛已经结束了有几天,但我各种忙,虽然AK但还是没来得及写题解.(我才不会告诉你我跑去学数据结构了) T1 区间方差 (就不贴题好了) 首先可以推公式(我们可以知道,线段树然而并不能通过初中学过的方差公式在log(L)内求出方差): (s2表示方差,L表示区间长度,xi表示区间的每一项,最后一个x上画了一根线表示这些数据的平均数) 用二项式定理完全平方公式可得: 再次展开: 另外,再代入以下这个 得到了: 然后继续吧.. 然后duang地一声合并同类项,于是我们得到了: 然后可以高

洛谷P2420 让我们异或吧

P2420 让我们异或吧 161通过 450提交 题目提供者该用户不存在 标签洛谷原创云端↑ 难度普及/提高- 时空限制1s / 128MB 提交  讨论  题解 最新讨论更多讨论 倍增可做的吧 玄学 更改根节点得分不一样- 这题面似乎对一些群体不太友- 这题为什么没数据 C++选手注意了 题目描述 异或是一种神奇的运算,大部分人把它总结成不进位加法. 在生活中-xor运算也很常见.比如,对于一个问题的回答,是为1,否为0.那么: (A是否是男生 )xor( B是否是男生)=A和B是否能够成为情

洛谷P1848 [USACO12OPEN]书架Bookshelf

当农夫约翰闲的没事干的时候,他喜欢坐下来看书.多年过去,他已经收集了 N 本书 (1 <= N <= 100,000), 他想造一个新的书架来装所有书. 每本书 i 都有宽度 W(i) 和高度 H(i).书需要按顺序添加到一组书架上:比如说,第一层架子应该包含书籍1 ... k,第二层架子应该以第k + 1本书开始,以下如此.每层架子的总宽度最大为L(1≤L≤1,000,000,000).每层的高度等于该层上最高的书的高度,并且整个书架的高度是所有层的高度的总和,因为它们都垂直堆叠. 请帮助农

[洛谷]P3613 睡觉困难综合征

题目大意:给出一棵n个点的树,每个点有一个运算符(与.或.异或)和一个数,支持两种操作,第一种修改一个点的运算符和数,第二种给出x,y,z,询问若有一个0~z之间的数从点x走到点y(简单路径),并且对路径上经过的点做对应的运算,最终最大能是多少.(n,操作数<=100,000,数字在[0,2^64)之间) 思路:洛谷改编NOI的一道神题,树剖/LCT维护若一开始全是0/全是1,经过一条链后各位会变成什么,用位运算合并信息,然后每个询问,从高位往低位贪心,每次取0和1中经过这条链后得到的较大值,若