• P1334 瑞瑞的木板 洛谷


    https://www.luogu.org/problem/show?pid=1334

    题目描述

    瑞瑞想要亲自修复在他的一个小牧场周围的围栏。他测量栅栏并发现他需要N(1≤N≤20,000)根木板,每根的长度为整数Li(1≤Li≤50,000)。于是,他神奇地买了一根足够长的木板,长度为所需的N根木板的长度的总和,他决定将这根木板切成所需的N根木板。(瑞瑞在切割木板时不会产生木屑,不需考虑切割时损耗的长度)瑞瑞切割木板时使用的是一种特殊的方式,这种方式在将一根长度为x的模板切为两根时,需要消耗x个单位的能量。瑞瑞拥有无尽的能量,但现在提倡节约能量,所以作为榜样,他决定尽可能节约能量。显然,总共需要切割N-1次,问题是,每次应该怎么切呢?请编程计算最少需要消耗的能量总和。

    输入输出格式

    输入格式:

    第一行: 整数N,表示所需木板的数量

    第2到N+1行: 每行为一个整数,表示一块木板的长度

    输出格式:

    一个整数,表示最少需要消耗的能量总和

    输入输出样例

    输入样例#1:
    3
    8
    5
    8
    
    输出样例#1:
    34
    

    说明

    将长度为21的木板,第一次切割为长度为8和长度为13的,消耗21个单位的能量,第二次将长度为13的木板切割为长度为5和8的,消耗13个单位的能量,共消耗34个单位的能量,是消耗能量最小的方案。

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstdio>
     4 #define maxn 20005
     5 #define LL long long
     6 
     7 using namespace std;
     8 
     9 LL n,x,size,ans,cnt;
    10 LL heap[maxn];
    11 
    12 void put(LL x)
    13 {
    14     LL now,next;
    15     size++;
    16     heap[size]=x;
    17     now=size;
    18     while(now>1)
    19     {
    20         next=now/2;
    21         if(heap[next]<=heap[now])    break;
    22         swap(heap[next],heap[now]);
    23         now=next;
    24     }
    25 }
    26 
    27 void pop()
    28 {
    29     LL now=1,next;
    30     heap[1]=heap[size];
    31     size--;
    32     while(now*2<=size)
    33     {
    34         next=now*2;
    35         if(next<size&&heap[next]>heap[next+1]) next++;
    36         if(heap[now]<=heap[next]) break;
    37         swap(heap[now],heap[next]);
    38         now=next;
    39     }
    40 }
    41 
    42 int main()
    43 {
    44     scanf("%lld",&n);
    45     for(int i=1;i<=n;i++)
    46     {
    47         cin>>x;
    48         put(x);
    49     }
    50     for(int i=1;i<n;i++)
    51     {
    52         cnt=heap[1];    pop();
    53         cnt+=heap[1];    pop();
    54         ans+=cnt;
    55         put(cnt);
    56     }
    57     printf("%lld",ans);
    58     return 0;
    59 }
    手打 小根堆 66ms / 16.17MB 代码:0.82KB
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <queue>
     4 #define maxn 20005
     5 #define LL long long
     6 
     7 using namespace std;
     8 
     9 LL n,x,size,ans,cnt;
    10 priority_queue<LL,vector<LL>,greater<LL> >que;
    11 
    12 int main()
    13 {
    14     scanf("%lld",&n);
    15     for(int i=1;i<=n;i++)
    16     {
    17         cin>>x;
    18         que.push(x);
    19     }
    20     for(int i=1;i<n;i++)
    21     {
    22         cnt=que.top();    que.pop();
    23         cnt+=que.top();    que.pop();
    24         ans+=cnt;
    25         que.push(cnt);
    26     }
    27     printf("%lld",ans);
    28     return 0;
    29 }
    优先队列 189ms / 16.4MB 代码:0.44KB
    ——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
  • 相关阅读:
    常用排序算法及java语言实现
    机器学习实战笔记(python3实现)01--概述
    笔试错题--(字符串常量池和JVM运行时数据区)
    笔试错题(典型题)
    java进阶--java网络编程
    01_Java基础_第1天(Java概述、环境变量、注释、关键字、标识符、常量)
    数据库3(DBUtils)
    数据库2(JDBC、DBUtils)
    数据库1(数据库、表及表数据、SQL语句)
    Linux的基本命令
  • 原文地址:https://www.cnblogs.com/Shy-key/p/6574179.html
Copyright © 2020-2023  润新知