懒省事的小明(nyoj 55)

来源:互联网 发布:js中json未定义 编辑:程序博客网 时间:2024/05/23 02:00

题目:点击打开链接


这题本来没有想到用优先队列……我首先想到的是用搜索……

正好借着这题再好好总结一下优先队列。

优先队列就是出队列的时候是有选择性的。

• 如果是普通的优先队列,priority_queue<int> q默认的出队列顺序是先大后小

• 如果想要出队列顺序是先小后大,那么可以自己写比较函数,或者用系统内置的比较函数greater<T>  (less<T>则是从大到小)

    且定义时:priority_queue<int, vector<int>, cmp >q或者priority_queue<int, vector<int>, greater<int> >q   其中第二个参数为容器类型,第三个参数为比较函数。

• 如果队列元素是结构体的话,这样定义priority_queue<node,  vector<node>, greater<node>>q是不行的,因为greater<node> 没有定义。这时就要通过重载<,注意不能重载>,因为标准库默认使用元素类型的<操作符来确定它们之间的优先级关系,重载>会出现编译错误。

    可以用友元重载:

    struct node
{

       int priority;
    
int value;

    friend bool operator< (node n1, node n2)
    {
        
return n1.priority > n2.priority;
    }

};

或者:

struct cmp

{
 bool operator() ( Node a, Node b )

{
   if( a.x==b.x )
           return a.y>b.y;
   return a.x>b.x;
 }

};

#include <stdio.h>#include <functional>#include <queue>using namespace std;/*struct cmp{int operator()(int &x, int &y){return x > y;}};priority_queue<int, vector<int>, cmp> q;可以自己写比较函数 */priority_queue<int, vector<int>, greater<int> > q;//greater<T>()是内置的比较函数,顺序是从大到小,//在头文件#include <functional>中 int main (void){int n, m, i;long long sum;scanf("%d", &n);while(n --){while(!q.empty())q.pop();scanf("%d", &m);int a;for(i = 0; i < m; i++){scanf("%d", &a);q.push(a);}sum = 0;int x, y;for(i = 0; i < m - 1; i++){x = q.top();q.pop();y = q.top();q.pop();x += y;sum += x;q.push(x);}printf("%lld\n", sum);}return 0;}

2014.5.27

看了题目第一反应是石子合并的题目,但是这个和石子合并不一样的地方在于石子合并只能合并相邻的两堆,而这题是任意两堆都可以。

0 0
原创粉丝点击