思路很简单 :每次如果车上有空的话,就尽量让最多的人上车,如果不空,就让后下车的部分人下车,换上早下车的人(这里需要维护一个结束站点的大根堆
细节: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);
}
小总结:思路不难想,但是实现有点烦人,借鉴了许多代码(((但还是贪心思想