【BZOJ】4977: [[Lydsy1708月赛]跳伞求生-贪心+模拟费用流

这是一篇关于BZOJ4977题目的解题报告,探讨了一个涉及贪心策略和模拟费用流的算法问题。在考虑成本ax - by + cy的情况下,如何优化选择降落点以满足每个房子最多容纳一个人的限制。题解中提到了维护a和b的前缀最大堆,并在遇到更优选择时进行类似费用流的退流操作,确保贪心算法的正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门:bzoj4977


题解

很妙的一个贪心

选择 ( x , y ) (x,y) (x,y)(x降落到y)的代价是 a x − b y + c y a_x-b_y+c_y axby+cy

如果没有一个房子只能容纳一个人的限制,就是维护 a , b a,b a,b前缀大小的堆,每次弹出栈顶的 − b i + c i -b_i+c_i bi+ci,代价加上 a x − b i + c i a_x-b_i+c_i axbi+ci(若堆为空或贡献 ≤ 0 \leq 0 0则不操作)

考虑存在 x , z ( x &lt; z ) x,z(x&lt;z) x,z(x<z) ( x , y ) (x,y) (x,y)是最优选择,但实际上 ( z , y ) (z,y) (z,y)更优,类似于费用流的退流操作,将 z z z所容纳的由 x x x改为 z z z,多了 a z − a x a_z-a_x azax的贡献,所以在 x x x弹出堆顶时,堆中加入 − a x -a_x ax表示修改。这样贪心正确性就没有问题了。


代码

#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值