7. 郭老师家的果园

郭老师家有个果园,每年到了秋收的时候都会收获很多不同种类的果子。他决定把所有的果子合成一堆,但由于体力有限,郭老师在每次合并的时候只能将两堆果子合并到一起。假设有 n 堆果子,那么经过 n-1 次合并即可完成任务,且消耗的总体力等于每次合并所消耗的体力之和。

因为郭老师还需要保留体力将果子运回家,所以在合并果子过程中要尽可能地节省体力。假定每个果子重量均为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合理的合并方案,使郭老师耗费的体力最少。

例如有3种果子,数目依次为1,2,9。合并方案如下:

1. 将1、2合并,得到新堆数目为3,耗费体力为3。

2. 将新堆与第三堆合并,又得到新堆,数目为12,耗费的体力为12。

3. 总共消耗体力为 3 + 12 = 15,可以证明15为最小的体力耗费值。

输入

输入包括两行,第一行是一个整数 n (1<=n<=10000),表示果子的种类数。第二行包含 n 个整数,用空格分隔,第 i 个整数 a(1<=ai<=10000)是第 i 种果子的数目。

输出

输出包括一行,这一行只包含一个整数,即最小的体力耗费值。输出的最小体力小于231


测试输入关于“测试输入”的帮助期待的输出关于“期待的输出”的帮助时间限制关于“时间限制”的帮助内存限制关于“内存限制”的帮助额外进程关于“{$a} 个额外进程”的帮助
测试用例 1以文本方式显示
  1. 3↵
  2. 1 2 9↵
以文本方式显示
  1. 15↵
1秒1024KB0


#include<stdio.h>
#include<stdlib.h>
#include<limits.h>

int last = 0,sum=0,len;
void FindMin(int num[])
{
	int x1 = last, x2 = last;
	int min = num[last];//定义最小
	int min2 = INT_MAX;//定义第二最小
	for (int i = last; i <len; i++) 
	{
		if (num[i]<min)
		{
			min = num[i];
			x1 = i;
		}
	}//获得最小
	for (int i = last; i < len; i++)
	{
		if (num[i] <= min2 && i!= x1)
		{
			min2 =num[i];
			x2 = i;
		}
	}//获得第二小
	num[x2] = min + min2;
	sum += num[x2];
	if (x2 == last)
		num[x1] = num[x2];
	else
		num[x1] = num[last];
	num[last] = 0;
	last++;
}
int main()
{
	int n;
	int num[10005] = { 0 };
	scanf("%d", &n);
	len = n;
	if (len == 1)
	{
		printf("%d\n", num[0]);
		return 0;
	}
	for (int i = 0; i < n; i++)
		scanf("%d", &num[i]);
	
	while (n > 1)
	{
		FindMin(num);
		n--;
	}
	printf("%d\n", sum);

	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值