傳送門:bzoj4977
題解
很妙的一個貪心
選擇(x降落到y)的代價是
如果沒有一個房子只能容納一個人的限制,就是維護前綴大小的堆,每次彈出棧頂的,代價加上(若堆爲空或貢獻則不操作)
考慮存在,是最優選擇,但實際上更優,類似於費用流的退流操作,將所容納的由改爲,多了的貢獻,所以在彈出堆頂時,堆中加入表示修改。這樣貪心正確性就沒有問題了。
代碼
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int n,m;ll ans;
struct node{int x,c;}d[N<<1];
inline bool cmp(node A,node B) {return A.x==B.x?A.c<B.c:A.x<B.x;}
priority_queue<int> q;
int main(){
int i;scanf("%d%d",&n,&m);
for(i=1;i<=n;++i) scanf("%d",&d[i].x),d[i].c=-1;
for(i=1;i<=m;++i) scanf("%d%d",&d[n+i].x,&d[n+i].c);
n+=m;sort(d+1,d+n+1,cmp);
for(i=1;i<=n;++i) {
if(d[i].c==-1) {
if(q.empty() || q.top()+d[i].x<=0) continue;
ans+=q.top()+d[i].x;
q.pop();q.push(-d[i].x);
}else q.push(d[i].c-d[i].x);
}
printf("%lld",ans);
return 0;
}