P7913(CSP2021)廊桥分配(堆)

题目传送门:传送门

对于该题,显然我们可以考虑维护 $sum1_i$ 表示给国内区分配 $i$ 个廊桥能停靠的最多飞机数,同理考虑维护 $sum2_i$ 表示给国际区分配 $i$ 个廊桥能停靠的最多飞机数。

此时显然会有 $ans=max(ans,sum1_{i}+sum2_{n-i})$ ,注意到此时 $i$ 的取值范围为 $[0,n]$。

再考虑如何维护 $sum1_i$ 与 $sum2_i$,显然对于国内区和国际区的航班处理属于同构问题,考虑处理一个即可。

对于国内区的航班,遵循“先到先得原则”,将航班按照到达时间先后排序。每次到达一个航班,我们将其分配给当前空闲的编号最小的廊桥,并把该廊桥设为已用。当该航班离开时,再将此廊桥设为空闲。显然这种贪心策略可以使用对顶堆进行实现。此时我们得到了,每个廊桥停靠的飞机编号及其数量,对廊桥停靠的飞机数量做前缀和即可得到我们想要维护的 $sum1_i$。国际区同理。总的时间复杂度为 $O(n + mlogm)$

P7913(CSP2021)廊桥分配(堆)
 1 #include<bits/stdc++.h>
 2 #define int long long
 3 using namespace std;
 4 const int N = 100000 + 10;
 5 struct arrive
 6 {
 7     int ls,rs;
 8 }a[N],b[N];
 9 typedef pair<int,int> point;
10 priority_queue < point,vector < point >,greater < point> > plane;
11 priority_queue< int,vector < int >,greater < int > > port;
12 int n,m1,m2,ans;
13 int f[N],g[N];
14 int sum1[N],sum2[N];
15 bool cmp(arrive aa,arrive bb)
16 {
17     return aa.ls < bb.ls;
18 }
19 signed main()
20 {
21     scanf("%lld%lld%lld",&n,&m1,&m2);
22     for(int i = 1;i <= m1;i++) scanf("%lld%lld",&a[i].ls,&a[i].rs);
23     for(int i = 1;i <= m2;i++) scanf("%lld%lld",&b[i].ls,&b[i].rs);
24     sort(a + 1,a + m1 + 1,cmp);
25     sort(b + 1,b + m2 + 1,cmp);
26     for(int i = 1;i <= n;i++) port.push(i);
27     for(int i = 1;i <= m1;i++)
28     {
29         while(not plane.empty() and a[i].ls >= plane.top().first)
30         {
31             port.push(plane.top().second);
32             plane.pop();
33         }
34         if(port.empty()) continue;
35         int pos = port.top();
36         port.pop();
37         f[pos]++;
38         plane.push(make_pair(a[i].rs,pos));
39     }
40     while(not port.empty()) port.pop();
41     while(not plane.empty()) plane.pop();
42     for(int i = 1;i <= n;i++) port.push(i);
43     for(int i = 1;i <= m2;i++)
44     {
45         while(not plane.empty() and b[i].ls >= plane.top().first)
46         {
47             port.push(plane.top().second);
48             plane.pop();
49         }
50         if(port.empty()) continue;
51         int pos = port.top();
52         port.pop();
53         g[pos]++;
54         plane.push(make_pair(b[i].rs,pos));
55     }
56     for(int i = 1;i <= n;i++) sum1[i] = sum1[i-1] + f[i];
57     for(int i = 1;i <= n;i++) sum2[i] = sum2[i-1] + g[i];
58     for(int i = 0;i <= n;i++) ans = max(ans,sum1[i] + sum2[n-i]);
59     printf("%lld\n",ans);
60     return 0;
61 }
View Code

 

上一篇:CSP2021(预&NOIP2021)游记


下一篇:CSP2021-04