priotity_queue 洛谷 2707

来源:互联网 发布:淘宝购物车排序规则 编辑:程序博客网 时间:2024/05/19 03:41

于是乎,我们要知道了如何要重载定义符!

重载

定义一

friend bool operator < (number x,number y){ return x.val<y.val;// 这是大根堆的应用!}

定义二

bool operator < (number &x) const{return ...;}

题面:

Facer的父亲是一名经理,现在总是垂头丧气的。
Facer问父亲,怎么啦?父亲说,公司出了点问题啊。
公司管理着N个风景点,每个风景点都有不少人来参观。
可是现在!人民投诉票价太高了,他不得不调整票价
具体来说,第i个景点如果票价是x,来的人数就是max( (ai - bi * x),0 )[收益自己算好伐]
你需要分配每个景点的门票,使得每个景点门票总和不超过k,且最大化收益=
求最大的收益

input:
2 4
50 2
40 1

output:
171

解释:

景点1票价3,景点2票价1
景点1人数:50 - 3*2 = 44 票价 :3 收益:132
景点2人数 : 40 - 1*1 = 39 票价 : 1 收益:39
总收益171 最大

思路:

我们其实会发现,对于每一个函数的值如果增长了 1 之后,对于答案的贡献就会增加一个表达的值!
就像这样!:
这里写图片描述
于是每一次在开一个堆,将增量分别推进大根堆里面!
每一次取出的时候就是只要将这个函数的x+1就好了,别的函数的治病不需要变!
具体就增量就是可以直接来求导一发就好了!
具体看代码

代码:

#include <bits/stdc++.h>#define ll long longusing namespace std;const int N = 101000;int n,k;ll ans,a[N],b[N];struct node{    int x,id;    long long add;    friend bool operator < (node first,node second)    {        return first.add < second.add;    }} make;priority_queue<node> final;int main(){    scanf("%d%d",&n,&k);    for(int i=1; i<=n; i++)        scanf("%d%d",&a[i],&b[i]);    for(int i=1; i<=n; i++)    {        make.x=1,make.add=a[i]+b[i]-2*b[i],make.id=i;        final.push(make);    }    for(int v=1; v<=k; v++)    {        node num=final.top();final.pop();        if(num.add<0) break;        ans+=num.add;        num.x++,num.add=a[num.id]+b[num.id]-2*b[num.id]*num.x;        final.push(num);    }    printf("%lld\n",ans);}
原创粉丝点击