洛谷 P1334 瑞瑞的木板==P2664 【题目待添加】

题目描述

瑞瑞想要亲自修复在他的一个小牧场周围的围栏。他测量栅栏并发现他需要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个单位的能量,是消耗能量最小的方案。

2664明显是copy的1334 只是改了改名字 

 

和合并果子一个做法 ,先切最小的俩 ,数据变大了 。

屠龙宝刀点击就送

#include <algorithm>
#include <cstdio>

typedef long long LL;
using namespace std;

LL z,Answer,N,l,size,heap[20000*4+1],i,j;
void heap_push(LL n)
{
    heap[++size]=n;
    LL pos=size;
    while(pos>1)
    {
        if(heap[pos]>=heap[pos/2]) break;
         if(heap[pos]<heap[pos/2])
        swap(heap[pos],heap[pos/2]);
        pos=pos/2;
    }
}
void heap_pop()
{
    heap[1]=heap[size--];LL pos=1;
    while(pos*2<=size)
    {
        LL next=pos*2;
        if(heap[next+1]<heap[next])    next++;
        if(heap[next]>heap[pos]) break;
        swap(heap[pos],heap[next]);
        pos=next;
    }
}
int main()
{
    scanf("%lld",&N);
    for(i=0;i<N;++i)
    {
        scanf("%lld",&l);
        heap_push(l);
        z+=l;
    }
    for(i=0;i<N-1;++i)
    {
        int top1=heap[1];heap_pop();
        int top2=heap[1];heap_pop();
        Answer+=top1+top2;
        heap_push(top1+top2);
    }
    printf("%lld\n",Answer);
    return 0;
}

 

posted @ 2017-03-02 19:45  杀猪状元  阅读(328)  评论(0编辑  收藏  举报