1577: [Usaco2009 Feb]庙会捷运Fair Shuttle
Description
公交车一共经过N(1<=N<=20000)个站点,从站点1一直驶到站点N。K(1<=K<=50000)群奶牛希望搭乘这辆公交车。第i群牛一共有Mi(1<=Mi<=N)只.
他们希望从Si到Ei去。
公交车只能座C(1<=C<=100)只奶牛。而且不走重复路线,请计算这辆车最多能满足多少奶牛听要求。
注意:对于每一群奶牛,可以部分满足,也可以全部满足,也可以全部不满足。
Input
第1行: 三个整数: K,N,C。 由空格隔开。
第2..K+1行:第i+1行,告诉你第i组奶牛的信息: S_i, E_i and M_i。由空格隔开。
Output
一行:可以在庙会乘坐捷运的牛的最大头数
Sample Input
8 15 3
1 5 2
13 14 1
5 8 3
8 14 2
14 15 1
9 12 1
12 15 2
4 6 1
1 5 2
13 14 1
5 8 3
8 14 2
14 15 1
9 12 1
12 15 2
4 6 1
Sample Output
10
思路:
贪心的选取上下车,线段树维护是否可以上车,贪心的正确性显然,代码如下
#include <cstdio> #include <algorithm> #include <cstring> #include <iostream> #define ls p<<1 #define rs p<<1|1 #define im int mid = (l + r) >> 1 using namespace std; const int N = 20000; const int inf = 0x3f3f3f3f; int k,n,c; int minn[N<<2],laz[N<<2]; int tmp,ans; struct cow { int s,t,m; }e[N<<2]; bool cmp(const cow &a,const cow &b) { return a.t==b.t?a.s>b.s:a.t<b.t; } void pushdown(int l,int r,int p,int s) { minn[p]+=s; laz[p]+=s; } void change(int l,int r,int p,int x,int y) { if(x<=l&&r<=y) { laz[p]+=tmp; minn[p]+=tmp; return ; } im; if(laz[p]) { pushdown(l,mid,ls,laz[p]); pushdown(mid+1,r,rs,laz[p]); laz[p]=0; } if(x<=mid) change(l,mid,ls,x,y); if(y>mid) change(mid+1,r,rs,x,y); minn[p]=max(minn[ls],minn[rs]); } void query(int l,int r,int p,int x,int y) { if(x<=l&&r<=y) { tmp=max(tmp,minn[p]); return ; } im; if(laz[p]) { pushdown(l,mid,ls,laz[p]); pushdown(mid+1,r,rs,laz[p]); laz[p]=0; } if(x<=mid) query(l,mid,ls,x,y); if(y>mid) query(mid+1,r,rs,x,y); } int main() { scanf("%d%d%d",&k,&n,&c); for(int i=1;i<=k;i++) { scanf("%d%d%d",&e[i].s,&e[i].t,&e[i].m); } sort(e+1,e+k+1,cmp); for(int i=1;i<=k;i++) { int tm; int s=e[i].s,t=e[i].t,m=e[i].m; tmp = 0; query(1,n,1,s,t-1); //printf("%d::::",tmp); if(tmp>=c)continue; if(tmp+m<=c)tm=m; else tm=c-tmp; tmp=tm; change(1,n,1,s,t-1); ans += tm; //printf("%d %d %d ",s,t,tmp); } printf("%d ",ans); }
欢迎来原博客看看 >原文链接<