隐藏
「2016四校联考-八中」火车运输 - 贪心 | Bill Yang's Blog

路终会有尽头,但视野总能看到更远的地方。

0%

「2016四校联考-八中」火车运输 - 贪心

题目大意

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;
}
姥爷们赏瓶冰阔落吧~