题目描述
在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。
每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所消耗体力之和。
因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。
例如有3种果子,数目依次为1,2,9。可以先将1、2堆合并,新堆数目为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为12。所以多多总共耗费体力=3+12=15。可以证明15为最小的体力耗费值。
输入
第一行是一个整数n(1<=n<=10000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个ai(1<=ai<=20000)是第i个果子的数目。
输出
输出包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输入数据保证这个值小于2^31。
示例输入
3
1 2 9
示例输出
15
1 #include<stdio.h>
2 #include<algorithm>
3 #include<iostream>
4 #include<queue>
5 using namespace std;
6
7 int main()
8 {
9 priority_queue<
int,vector<
int>,greater<
int> >
que;
10 int n,x,a,b,ans;
11 while(!
que.empty())
12 que.pop();
13 scanf(
"%d",&
n);
14 while(n--
)
15 {
16 scanf(
"%d",&
x);
17 que.push(x);
18 }
19 ans =
0;
20 while(!
que.empty())
21 {
22 a =
que.top();
23 que.pop();
24 if(que.empty())
25 break;
26 else
27 {
28 b =
que.top();
29 que.pop();
30 a = a+
b;
31 ans +=
a;
32 que.push(a);
33 }
34 }
35 printf(
"%d\n",ans);
36 return 0;
37 }
View Code
1 View Code
2 #include<iostream>
3 #include<algorithm>
4 #define N 12010
5
6 using namespace std;
7
8 long long a[N];
9
10 long long work(
int n)
11 {
12 long long t,ans=
0;
13 int i,j;
14 if(n==
1)
return 0;
15 for(i=
1;i<n;i++
)
16 {
17 ans=ans+a[i]+a[i-
1];
18 a[i]=a[i]+a[i-
1];
19 j=i+
1;
20 bool flag=
true;
21 for(;a[j-
1]>a[j]&&j<n;j++
)
22 {
23 t=a[j-
1];a[j-
1]=a[j];a[j]=
t;
24 }
25 }
26 return ans;
27 }
28
29 int main()
30 {
31 int test;
32 cin>>
test;
33 while(test--
)
34 {
35 int n,i;
36 cin>>
n;
37 for(i=
0;i<n;i++
)
38 cin>>
a[i];
39 sort(a,a+
n);
40 cout<<work(n)<<
endl;
41 }
42 return 0;
43 }
View Code
转载于:https://www.cnblogs.com/LK1994/p/3162239.html
相关资源:JAVA上百实例源码以及开源项目