priotity_queue 洛谷 2707

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

重载

定义一

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 long
using 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);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值