YBTOJ H. 4.火车载客

思路很简单 :每次如果车上有空的话,就尽量让最多的人上车,如果不空,就让后下车的部分人下车,换上早下车的人(这里需要维护一个结束站点的大根堆

细节:1.对于数据需要先进行排序    2.先下后上 3.对于每一次处理,上车时需要对原数据的标记进行处理(有点抽象,看code

#include<bits/stdc++.h>
#define re register
#define ll long long
#define int long long
#define inl inline
using namespace std;
int read(){
	int sum=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
	while(isdigit(c)){sum=(sum<<3)+(sum<<1)+(c^48);c=getchar();}
	return sum*f;
}
const int N=3e5+10;
struct train{
	int st,ed,num,id;
}a[N<<1];
struct T{
	int time,id,op;
}b[N<<1];
bool cmp(T a,T b){
	return a.time!=b.time?a.time<b.time:a.op>b.op;
}
bool operator>(const train& a,const train& b){return a.ed<b.ed;}
bool operator<(const train& a,const train& b){return a.ed<b.ed;}
priority_queue<train> q;
signed main(){
	int k=read(),n=read(),c=read(),tot=0,sum=0,ans=0;
	for(re int i=1;i<=k;i++){
		int s=read(),t=read(),p=read();
		a[i]=(train){s,t,p,0};
		b[++tot]=(T){s,i,0};
		b[++tot]=(T){t,i,1};
	}
	sort(b+1,b+1+tot,cmp);
	for(re int i=1;i<=tot;i++){
		int id=b[i].id;
		if(b[i].op==0){
			while(!q.empty()&&q.top().ed<b[i].time){
				a[q.top().id].id=0;
				q.pop();
			}
			while(sum<c&&a[id].num){
				int add=min(c-sum,a[id].num);
				a[id].id+=add;
				a[id].num-=add;
				q.push((train){a[id].st,a[id].ed,add,id});
				sum+=add;
			}
			while(!q.empty()&&a[id].num&&a[id]<q.top()){
				train tmp=q.top();q.pop();
				int add=min(a[id].num,tmp.num);
				tmp.num-=add;
				a[tmp.id].id-=add;
				a[id].id+=add;
				a[id].num-=add;
				if(tmp.num) q.push(tmp);
				q.push((train){a[id].st,a[id].ed,add,id});
			}
		}
		else{
			ans+=a[id].id;
			sum-=a[id].id;
			a[id].id=0;
		}
	}
	printf("%d",ans);
}

小总结:思路不难想,但是实现有点烦人,借鉴了许多代码(((但还是贪心思想

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值