noip 2004 合并果子

合并果子

Time Limit:1000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu

Description

现在有n堆果子,第i堆有ai个果子。现在要把这些果子合并成一堆,每次合并的代价是两堆果子的总果子数。求合并所有果子的最小代价。

Input

第一行包含一个整数T(T<=50),表示数据组数。
每组数据第一行包含一个整数n(2<=n<=1000),表示果子的堆数。
第二行包含n个正整数ai(ai<=100),表示每堆果子的果子数。

Output

每组数据仅一行,表示最小合并代价。

Sample Input

2
4
1 2 3 4
5
3 5 2 1 4

Sample Output

19
33

树和STL优先队列也能做,题目思想很明确,用贪心做出。
先用STL中的 priority_queue<int , vector<int> ,greater<int> > x  函数,即优先队列,把最小的两个数相加。
在 priority_queue<int , vector<int> ,greater<int> > x ,x表示一个“越小的整数优先级越大的优先队列” ,
#include<cstdio>
#include<cstring>
#include<iostream>
#include<utility>
#include<string>
#include<vector>
#include<algorithm>
#include<queue>
#include<cstdlib>
#include<cmath>
#include<stack>

using namespace std;

priority_queue<int , vector<int> ,greater<int> > x ;

int main()
{
#ifndef ONLINE_JUDGE
	freopen("1.txt","r",stdin);
#endif
	int t;
	cin >> t ;
	while (t--)
	{
		int n , i , a[1005] , ans = 0 ;
		cin >> n ;
		for(i = 0 ; i < n ; ++i)
		{
			cin >> a[i] ;
			x.push(a[i]);
		}
		while(x.size() > 1)
		{
			n = x.top() ;
			x.pop();
			n += x.top() ;
			x.pop();
			ans += n ;
			if(x.empty())break;
			x.push(n);
		}
		printf("%d\n",ans);
	}

	return 0;
}

而单单的 priority_queue<int> x 则可以表示为一个 “越小的整数优先级越低的优先队列”。
### NOIP 2004 提高组 合并果子 Python 解题思路 #### 背景描述 合并果子问题是经典的贪心算法题目之一。给定若干堆果子的数量,每次可以选取两堆数量最少的果子将其合并成一堆,并记录此次合并所花费的成本(即这两堆果子数之和)。最终目标是最小化总成本。 #### 思路分析 为了最小化合并过程中的总成本,应该优先考虑将较小的两堆先合并起来。这样做的好处是可以减少后续较大规模合并时所需付出的成本。具体来说: - 使用一个小根堆来存储每堆果子的数量。 - 每次取出两个最小值进行合并操作,并把新得到的结果重新放回堆中继续参与下一轮比较。 - 记录每一次合并产生的费用直到只剩下一堆为止[^1]。 #### 实现方法 基于上述策略,在Python编程语言环境下可以通过`heapq`模块轻松构建这样一个高效的小顶堆结构来进行求解。 ```python import heapq def min_cost_to_merge_fruits(fruit_piles): # 将所有的果子堆加入到一个列表里, 并转换为最小堆 heapq.heapify(fruit_piles) total_cost = 0 while len(fruit_piles) > 1: # 取出当前最小的两堆果子 first_min = heapq.heappop(fruit_piles) second_min = heapq.heappop(fruit_piles) current_cost = first_min + second_min # 更新总的消耗代价 total_cost += current_cost # 把这次合并后的结果再加回到堆里面去 heapq.heappush(fruit_piles, current_cost ) return total_cost ``` 此函数接收一个整型数组作为输入参数,代表初始状态下各堆果子的具体数目;返回的是完成全部合并不需要额外空间复杂度下的最低可能耗费时间/次数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值