游客 Signup | Login
中文 | En

3603 - 合并石子

     小Ray在河边玩耍,无意中发现一些很漂亮的石子堆,于是他决定把这些石子搬回家。河滩上一共有n(1≤n≤30000)堆石子,每次小Ray合并两个石子数最少的两堆石子成为一堆。经过n-1次合并操作以后,只剩下一堆石子,然后小Ray就将这一堆石子搬回家。每合并两堆石子的时候,小Ray消耗的体力是两堆石子的数量之和。请你算一算,小Ray合并所有石子堆消耗的体力是多少呢。

Input

第一行输入n,表示n堆石子。

第二行输入n堆石子的数量。

Output

输出一行表示消耗的体力。

Examples

Input

5
1 2 3 4 5 

Output

33

Solution C

#include<stdio.h>

int main(){
	int x[30005],b[30005]={0},i,j,n,m1,m2,j1,j2,sum=0;
	scanf("%d",&n);
	for(i=0;i<n;i++)
		scanf("%d",&x[i]);
	for(j=1;j<n;j++){
		m1=m2=1000000000;j1=j2=0;
		for(i=0;i<n;i++)
			if(b[i]==1)continue;
			else if(x[i]<m1)
			{
				if(x[i]<m2){m1=m2;j1=j2;m2=x[i];j2=i;}
				else{m1=x[i];j1=i;}
			}	
		x[j2]=x[j1]+x[j2];
		sum+=x[j2];
		b[j1]=1;
	}
	printf("%d\n",sum);
	return 0;
}

Solution C++

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
 
using namespace std;
 
priority_queue <int> que;
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0,x;i<n;++i)
    {
        scanf("%d",&x);
        que.push(-x);
    }
    int ans=0;
    for(int i=1,tmp;i<n;++i)
    {
        tmp=que.top();
        ans-=que.top();
        que.pop();
        tmp+=que.top();
        ans-=que.top();
        que.pop();
        que.push(tmp);
    }
    cout<<ans<<endl;
    return 0;
}
Time Limit 1 second
Memory Limit 128 MB
Discuss Stats
上一题 下一题