题目大意
ByteLand火车站(编号$0$)每天都要发往全国各地$N$列客运火车,编号$1\rightarrow N$。第$i$列火车的目的地是编号$S_i$的火车站。
对任意车站$X$,都与$X+1$车站有铁轨直接相连,因此火车站可以看成数轴上的整数点,第$i$列火车可以停靠区间$[0,S_i]$中的各个站点。每列火车装载乘客的最大容量为$C_i$。
有$M$个人需要乘坐火车。已知每个人的乘车区间为$[L_i, R_i]$,即是说,在$L_i$上车,在$R_i$下车。由于火车的容量限制,请你求出最多有多少人的乘车需求可以得到满足。
题目分析
很神奇的贪心。
考虑每一个人$i$去选择火车,贪心策略:选择$S_j\ge R_i$的第一个火车$j$。
考虑一个人$i$若乘坐了火车$j$,那么火车实际上被拆分成了两个火车,一个火车$0\rightarrow L_i$,容量为$1$,另一个火车$0\rightarrow S_j$,容量$c_j-1$。
如果我们要使得火车的利用价值最大,那么人应该按照左端点$L$从大到小一个一个选火车,这样可以使火车利用价值最大。
我们可以用map来实现这个过程,在map中找到第一个大于$R_i$的火车,将火车拆分后再次放入map,计算可选个数。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| #include<algorithm> #include<iostream> #include<iomanip> #include<cstring> #include<cstdlib> #include<vector> #include<cstdio> #include<cmath> #include<set> #include<map> using namespace std; inline const int Get_Int() { int num=0,bj=1; char x=getchar(); while(x<'0'||x>'9') { if(x=='-')bj=-1; x=getchar(); } while(x>='0'&&x<='9') { num=num*10+x-'0'; x=getchar(); } return num*bj; } struct Person { int l,r; bool operator < (const Person& b) const { return l>b.l||(l==b.l&&r>b.r); } } a[100005]; int n,m,ans=0; map<int,int>M; int main() { n=Get_Int(); m=Get_Int(); for(int i=1; i<=n; i++) { int s=Get_Int(),c=Get_Int(); M[s]+=c; } for(int i=1; i<=m; i++) { a[i].l=Get_Int(); a[i].r=Get_Int(); } sort(a+1,a+m+1); for(int i=1; i<=m; i++) { auto it=M.lower_bound(a[i].r); if(it!=M.end()) { it->second--; if(!it->second)M.erase(it); M[a[i].l]++; ans++; } } printf("%d\n",ans); return 0; }
|