优先队列题目

Problem Description

Farmer John wants to repair a small length of the fence around the pasture. He measures the fence and finds that he needs N (1 ≤ N ≤ 20,000) planks of wood, each having some integer length Li (1 ≤ Li ≤ 50,000) units. He then purchases a single long board just long enough to saw into the N planks (i.e., whose length is the sum of the lengths Li). FJ is ignoring the "kerf", the extra length lost to sawdust when a sawcut is made; you should ignore it, too.

FJ sadly realizes that he doesn't own a saw with which to cut the wood, so he mosies over to Farmer Don's Farm with this long board and politely asks if he may borrow a saw.

Farmer Don, a closet capitalist, doesn't lend FJ a saw but instead offers to charge Farmer John for each of the N-1 cuts in the plank. The charge to cut a piece of wood is exactly equal to its length. Cutting a plank of length 21 costs 21 cents.

Farmer Don then lets Farmer John decide the order and locations to cut the plank. Help Farmer John determine the minimum amount of money he can spend to create the N planks. FJ knows that he can cut the board in various different orders which will result in different charges since the resulting intermediate planks are of different lengths.

 

Input
Line 1: One integer N, the number of planks
Lines 2..N+1: Each line contains a single integer describing the length of a needed plank
 

Output
Line 1: One integer: the minimum amount of money he must spend to make N-1 cuts
 

Sample Input
3 8 5 8
 

Sample Output
34
 

ac代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<queue> 
#include<algorithm>
#define MAXN 101000
using namespace std;
struct s
{
	int num;
	friend bool operator<(s a,s b)
	{
		return a.num>b.num;
	}
}a,b,c;
priority_queue<s>q;
int main()
{
	int n,i;
	while(scanf("%d",&n)!=EOF)
	{
		for(i=0;i<n;i++)
		{
			scanf("%d",&a.num);
			q.push(a);
		}
		long long sum=0;
		while(q.size()!=1)
		{
			b=q.top();
			q.pop();
			c=q.top();
			q.pop();
			a.num=b.num+c.num;
			sum+=a.num;
			q.push(a);
		}
		printf("%lld\n",sum);
	}
	return 0;
} 


### 蓝桥杯中的优先队列题目及其解题思路 #### 什么是优先队列优先队列是一种特殊的队列,其中每个元素都有一个关联的优先级。当从优先队列中取出元素时,总是返回具有最高优先级的元素(或者最低优先级,取决于实现方式)。通常可以通过堆这种数据结构来高效地实现优先队列。 在蓝桥杯竞赛中,涉及优先队列题目往往考察选手对贪心算法、动态规划以及高级数据结构的理解能力。以下是关于如何解决这类问题的一些常见方法和技巧: #### 常见应用场景 1. **资源分配类问题** 这些问题是典型的优先队列应用案例之一,在某些情况下需要根据特定条件最优地分配有限资源给多个请求者。例如安排学生到不同大小桌子就餐的问题[^3]。 2. **滑动窗口最值计算** 尽管此场景更常与双端队列联系在一起,但在处理更加复杂的约束条件下也可以引入优先队列辅助求解。比如寻找数组中长度固定的子区间内的最大最小值等问题[^2]。 #### 使用优先队列解决问题的一般策略 - 构建合适的比较函数定义好何谓“高优先生存”的标准; - 利用STL库提供的`priority_queue<T>`模板容器快速搭建框架;注意默认大顶堆行为可能需调整为小顶形式满足实际需求; - 结合具体业务逻辑不断维护更新当前状态直至得出最终结果为止。 下面给出一段利用C++ STL priority_queue完成基本操作演示代码如下所示: ```cpp #include <iostream> #include <queue> using namespace std; int main(){ // 默认创建的是大根堆(最大值位于顶部) priority_queue<int> pq; int values[] = {7, 10, 4, 3, 20 ,15}; for(auto val : values){ pq.push(val); } cout << "Elements in Priority Queue:" << endl; while(!pq.empty()){ cout<<pq.top()<<" "; pq.pop(); } } ``` 上述程序展示了怎样向优先队列添加一系列整数并逐一弹出它们的过程。由于采用了大根堆模式,所以每次调用top()都会获取剩余集合里的最大数值直到整个序列被耗尽。 #### 经典例题解析——餐厅座位安排 假设现在有若干张圆桌可供顾客就坐用餐,每张桌子上能容纳固定数量的人一起共享美食体验。已知一批待服务食客各自所需空间不完全相同,请问最少准备多少套这样的设施才能让所有人满意? ##### 思路分析 这个问题实际上就是要求我们找到一种最佳组合方案使得总的开销达到最小化目标。考虑到每个人占用面积差异较大这一特性,很自然联想到应该把那些占据更多位置的大户安置于单独房间内独立享用佳肴比较好。于是乎我们可以尝试借助二分查找配合验证机制逐步逼近理想答案边界范围之内再通过模拟测试确认可行性与否进而锁定确切数目作为最后答复提交即可。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值