优先队列 UVA 10954

优先队列:顾名思义,首先它是一个队列,但是它强调了“优先”二字,所以,已经不能算是一般意义上的队列了,它的“优先”意指取队首元素时,有一定的选择性,即根据元素的属性选择某一项值最优的出队~
百度百科上这样描述的:
  优先级队列 是不同于先进先出队列的另一种队列。每次从队列中取出的是具有最高优先权的元素
  优先队列的类定义  
  优先队列是0个或多个元素的集合,每个元素都有一个优先权或值,对优先队列执行的操作有1) 查找;2) 插入一个新元素;3) 删除.在最小优先队列(min priorityq u e u e)中,查找操作用来搜索优先权最小的元素,删除操作用来删除该元素;对于最大优先队列(max priority queue),查找操作用来搜索优先权最大的元素,删除操作用来删除该元素.优先权队列中的元素可以有相同的优先权,查找与删除操作可根据任意优先权进行. 
优先队列,其构造及具体实现我们可以先不用深究,我们现在只需要了解其特性,及在做题中的用法,相信,看过之后你会收获不少。
使用优先队列,首先要包函STL头文件"queue"。
1.普通方法:
[cpp] view plain copy
priority_queue<int>qu;  




对入队的元素默认按照从大到小排序。
2.自定义优先级:
[cpp] view plain copy
struct cmp{  
  bool operator()(int x,int y)  
{  
    return x>y;   //从小到大排序。即x小的优先级高。  
}  
};  
  
priority_queue<int,vector<int>,cmp>qu;  






3.对结构体进行重载操作符:
[cpp] view plain copy
struct node {  
   int x,y;  
   friend bool operator < (node a, node b)  
   {  
       return a.x>b.x;    //x小的优先级高。  
   }  
};  




也可以:
[cpp] view plain copy
struct node{  
int x,y;  
};  
bool operator(const node &a,const node &b)  
{  
return a.x>b.x;  
};  
  
  
priority_queue<node>qu;  








Yup!! The problem name reflects your task; just add a set of numbers. But you may feel yourselves
condescended, to write a C/C++ program just to add a set of numbers. Such a problem will simply
question your erudition. So, lets add some flavor of ingenuity to it.
Addition operation requires cost now, and the cost is the summation of those two to be added. So,
to add 1 and 10, you need a cost of 11. If you want to add 1, 2 and 3. There are several ways
1 + 2 = 3, cost = 3 1 + 3 = 4, cost = 4 2 + 3 = 5, cost = 5
3 + 3 = 6, cost = 6 2 + 4 = 6, cost = 6 1 + 5 = 6, cost = 6
Total = 9 Total = 10 Total = 11
I hope you have understood already your mission, to add a set of integers so that the cost is minimal.
Input
Each test case will start with a positive number, N (2 ≤ N ≤ 5000) followed by N positive integers
(all are less than 100000). Input is terminated by a case where the value of N is zero. This case should
not be processed.
Output
For each case print the minimum total cost of addition in a single line.
Sample Input
3
1 2 3
4
1 2 3 4
0
Sample Output
9
19


解决方案:一开始思路就有点错了,要先加最小的那两个,然后这两个数就替换成了两者之和,再从新的数组里寻找两个最小的。
如果每次都对新的数组排序的话,会很耗时,所以可用优先队列。
#include <cstdio>  
#include <cstring>  
#include <queue>  
#include <vector>  
#include <algorithm>  
using namespace std; 
struct cmp
{  
	  bool operator()(int x,int y)  
	{  
	    return x>y;   //从小到大排序。即x小的优先级高。  
	}  
};  
 
int main() {  
    int n;  
    while(scanf("%d",&n) != EOF && n) {  
	    priority_queue<int,vector<int>,cmp>q;  
       // priority_queue<int,vector<int>,greater<int> > q;  
        int num;      
        for(int i = 0; i < n; i++) {  
            scanf("%d",&num);  
            q.push(num);  
        }  
        int cost,sum = 0;  
        int tmp1,tmp2;  
        while(q.size() >= 2) {  
            tmp1 = q.top();  
            q.pop();  
            tmp2 = q.top();  
            q.pop();  
            cost = tmp1 + tmp2;  
            sum += cost;  
            q.push(cost);  
        }  
        printf("%d\n",sum);  
    }  
    return 0;  
}  


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值