寒假篇3-合并果子
2017-01-13 09:58
190 查看
2004年分区联赛提高组之二 合并果子
Time Limit:20000MS Memory Limit:65536K
Total Submit:567 Accepted:254
Case Time Limit:5000MS
Description
在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。
每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。
因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。
例如有3种果子,数目依次为1,2,9。可以先将1、2堆合并,新堆数目为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为12。所以多多总共耗费体力=3+12=15。可以证明15为最小的体力耗费值。
Input
输入包括两行,第一行是一个整数n(1<=n<=10000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1<=ai<=20000)是第i种果子的数目。
Output
输出包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输入数据保证这个值小于231。
Sample Input
3
1 2 9
Sample Output
15
Hint
对于30%的数据,保证有n<=1000:
对于50%的数据,保证有n<=5000;
对于全部的数据,保证有n<=10000。
做法:本题正解好像说使用堆做,不过我根据题意直接可以用一种类似模拟的方法写,用一个数组记录初始的,另一个数组记录每次和并后的,用两个指针标记当前找到这两个数组的那个位置,比较,哪个小就加那个。除去排序的话是O(n)的。
代码如下(Pascal好久以前做过的)
Time Limit:20000MS Memory Limit:65536K
Total Submit:567 Accepted:254
Case Time Limit:5000MS
Description
在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。
每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。
因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。
例如有3种果子,数目依次为1,2,9。可以先将1、2堆合并,新堆数目为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为12。所以多多总共耗费体力=3+12=15。可以证明15为最小的体力耗费值。
Input
输入包括两行,第一行是一个整数n(1<=n<=10000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1<=ai<=20000)是第i种果子的数目。
Output
输出包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输入数据保证这个值小于231。
Sample Input
3
1 2 9
Sample Output
15
Hint
对于30%的数据,保证有n<=1000:
对于50%的数据,保证有n<=5000;
对于全部的数据,保证有n<=10000。
做法:本题正解好像说使用堆做,不过我根据题意直接可以用一种类似模拟的方法写,用一个数组记录初始的,另一个数组记录每次和并后的,用两个指针标记当前找到这两个数组的那个位置,比较,哪个小就加那个。除去排序的话是O(n)的。
代码如下(Pascal好久以前做过的)
var n,i,l1,l2,r1,r2,s,ans:longint; a,b:array[0..20000] of longint; procedure qsort(l,r:longint); var i,j,k:longint; begin if l>=r then exit; i:=l; j:=r; k:=a[(i+j) div 2]; repeat while a[i]<k do inc(i); while a[j]>k do dec(j); if i<=j then begin a[0]:=a[i];a[i]:=a[j];a[j]:=a[0]; inc(i);dec(j); end; until i>j; qsort(i,r); qsort(l,j); end; begin readln(n); fillchar(a,sizeof(a),$7f div 3); for i:=1 to n do read(a[i]); qsort(1,n); l1:=1; r1:=n; fillchar(b,sizeof(b),$7f div 3); l2:=1; for i:=1 to n-1 do begin s:=0; if a[l1]<b[l2] then begin s:=s+a[l1]; inc(l1); end else begin s:=s+b[l2]; inc(l2); end; if a[l1]<b[l2] then begin s:=s+a[l1]; inc(l1); end else begin s:=s+b[l2]; inc(l2); end; inc(r2); b[r2]:=s; ans:=ans+s; end; writeln(ans); end.
相关文章推荐
- 树-堆结构练习——合并果子之哈夫曼树
- 合并果子----(堆的应用)
- 合并果子(multiset)
- 合并果子
- 合并果子解题报告
- 洛谷P1090-合并果子-题解
- 合并果子 (优先队列小根堆)
- [一堆一堆又一堆]合并果子
- 单调队列及其deque写法 HDU 3415+Poj 4002 (日期处理) + 合并果子
- 【堆排】合并果子
- 合并果子
- Luogu-p1090 合并果子(优先队列)
- 18-03-09 P1090 合并果子
- 合并果子
- 树-堆结构练习——合并果子之哈夫曼树
- 合并果子
- AHOI1997彩旗飘飘 VIJOS1097合并果子(noip2007)
- CodeVS 1063 合并果子 题解
- sdut 2127 树-堆结构练习——合并果子之哈夫曼树
- 【Luogu P1090】合并果子