【u009】瑞瑞的木板

来源:互联网 发布:sql注入防范论文 编辑:程序博客网 时间:2024/04/27 18:01

Time Limit: 1 second
Memory Limit: 128 MB

【问题描述】

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


【输入格式】

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

【输出格式】

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

【数据规模】

Sample Input1

3858

Sample Output1

34

【样例说明】

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

这题需要反过来想。

把一块长木板分成n个小木板,它的逆过程。就是

把n块小木板拼成1块长木板。

然后本来是每次消耗所需要切割的长度的体力。

现在变成消耗掉两块木板拼起来的长度等价的体力。

然后依然是操作n-1次。

则。每次只要选择最短和次短的两块木板拼起来就可以了。这样可以保证每次进行的操作都是花费最小的。

而维护最小值。需要用到堆(小根堆)。

【代码】

#include <cstdio>__int64 dui[20001] = { 0 };//记录堆的信息。小根堆。int n,pos;void up_adjust(int p)//从位置p开始往上调整堆。{__int64 x = dui[p];//先记录堆中这个元素的大小。int i = p, j = p / 2;while (j > 0)//如果还没到根节点。{if (x < dui[j])//如果需要调整则调整{dui[i] = dui[j];i = j;j = i / 2;}else//不需要调整了就结束。break;}dui[i] = x;pos = i;//记录下新的位置。方便继续尝试往下调整。}void down_adjust(int p)//从位置p开始往下调整{__int64 x = dui[p];int i = p, j = p * 2;while (j <= dui[0])//如果没到叶子节点{if (j < dui[0] && dui[j + 1] < dui[j])//如果右儿子更小则和右儿子尝试交换。j++;if (x > dui[j])//如果需要调整,则调整。{dui[i] = dui[j];i = j;j = i * 2;}elsebreak;}dui[i] = x;//把这个元素放到新的位置。}void input_data(){scanf("%d", &n);//输入数据for (int i = 1; i <= n; i++)//依次把n个数据加入到堆中去。{int x;scanf("%d", &x);dui[0]++;dui[dui[0]] = x;up_adjust(dui[0]);//因为加到叶子节点。所以要先往上调整。down_adjust(pos);//然后再往下调整。}}void get_ans(){__int64 ans = 0;//答案一开始为0for (int i = 1; i <= n - 1; i++){__int64 x = dui[1];//取出一个元素。进行调整dui[1] = dui[dui[0]];dui[0] --;down_adjust(1);__int64 y = dui[1];//再取出另一个次小的。再调整。dui[1] = dui[dui[0]];dui[0]--;down_adjust(1);__int64 z = x + y;//把这两个木块拼在一起。ans += z;//累加答案。dui[0]++;//把拼出来的新木板再加入到堆中去。dui[dui[0]] = z;up_adjust(dui[0]);//向上调整。再向下调整即可。down_adjust(pos);}printf("%I64d\n", ans);}int main(){input_data();get_ans();return 0;}


0 0
原创粉丝点击