於是乎,我們要知道了如何要重載定義符!
重載
定義一
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 1output:
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);
}