寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄寄|

TLE_Automation

园龄:2年9个月粉丝:19关注:23

P7913 [CSP-S 2021] 廊桥分配

Solution

更新一下,之前写的太烂了。

首先我们能想到一个暴力算法,就是枚举分配到国内区和国外区的廊桥个数,然后用两个优先队列来模拟,复杂度 O(n2logn)

预计得分: 40

然后我们考虑,当一个区的廊桥数确定为 x 的时候,另一个廊桥数是 nx

当一个区的廊桥数增加的时候,他能停靠的飞机只增不减。

如果我们给廊桥标上号,当增加廊桥数目之后,之前停靠在廊桥上的飞机不会停到新增加的廊桥上。

如果每一遍都模拟,复杂度过高,当一个区为 x+1 个廊桥时,我们可以利用有 x 个廊桥的结果算出 x+1 的结果。

res1i 表示在国内区前 i 个廊桥能停靠的飞机个数,res2i 表示在国际区前 i 个廊桥能停靠的飞机个数。

我们可以通过前缀和来实现这个数组的求出,也就是求出每个廊桥可以停靠的飞机个数,我们可以维护两个优先队列,一个是空闲的廊桥,一个是要离开的飞机所停靠的廊桥。

这个过程的话,用什么数据结构维护一下就行了。

但是个人觉得 set 最简洁。

复杂度 O(nlogn), 预计得分 100

/*
Work by: TLE_Automation
*/
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
#define int long long
using namespace std;
const int N = 1e6 + 10;
const int MAXN = 2e5 + 10;
inline char readchar() {
static char buf[100000], *p1 = buf, *p2 = buf;
return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;
}
inline int read() {
#define readchar getchar
int res = 0, f = 0;char ch = readchar();
for(; !isdigit(ch); ch = readchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = readchar()) res = (res << 1) + (res << 3) + (ch ^ '0');
return f ? -res : res;
}
inline void print(int x) {
if (x < 0 ) putchar('-'), x = -x;
if (x > 9 ) print(x / 10);
putchar(x % 10 + '0');
}
typedef pair <int, int> p;
struct Node {
int st, ed;
bool operator < (const Node &x) const {
return st < x.st;
}
}a[MAXN], b[MAXN];
int res1[MAXN], res2[MAXN], ans = 0;
priority_queue <p, vector <p>, greater <p> > q1;
priority_queue <int, vector <int>, greater <int> > q2;
signed main() {
int n = read(), m1 = read(), m2 = read();
for(int i = 1; i <= m1; i++) a[i].st = read(), a[i].ed = read();
for(int i = 1; i <= m2; i++) b[i].st = read(), b[i].ed = read();
sort(a + 1, a + m1 + 1), sort(b + 1, b + m2 + 1);
for(int i = 1; i <= n; i++) q2.push(i);
for(int i = 1; i <= m1; i++) {
while(!q1.empty() && a[i].st >= q1.top().first) q2.push(q1.top().second), q1.pop();
if(q2.empty()) continue;
int wz = q2.top(); q2.pop();
res1[wz]++; q1.push(make_pair (a[i].ed, wz));
}
while(!q1.empty()) q1.pop();
while(!q2.empty()) q2.pop();
for(int i = 1; i <= n; i++) q2.push(i);
for(int i = 1; i <= m2; i++) {
while(!q1.empty() && b[i].st >= q1.top().first) q2.push(q1.top().second), q1.pop();
if(q2.empty()) continue;
int wz = q2.top(); q2.pop();
res2[wz]++; q1.push(make_pair (b[i].ed, wz));
}
for(int i = 1; i <= n; i++) res1[i] += res1[i - 1], res2[i] += res2[i - 1];
for(int i = 0; i <= n; i++)
ans = max(ans, res1[i] + res2[n - i]);
cout << ans;
}

set 做法:

#include<bits/stdc++.h>
using namespace std;
const int Maxn = 1e5 + 10;
int n, m1, m2, res1[Maxn], res2[Maxn], Maxx = 0;
std::set <std::pair <int, int> > qwq, qaq;
void Work(std::set <std::pair<int, int> > s, int res[] ) {
for(int i = 1; i <= n; i++) {
int pos = 0, ans = 0;
for(auto it = s.begin(); it != s.end(); it = s.lower_bound(make_pair(pos, 0))) {
ans++, pos = it -> second, s.erase(it);
}
res[i] = res[i - 1] + ans;
}
}
int main() {
scanf("%d %d %d", &n, &m1, &m2);
for(int i = 1, l, r; i <= m1; i++)
scanf("%d %d", &l, &r), qwq.insert(make_pair(l, r));
for(int i = 1, l, r; i <= m2; i++)
scanf("%d %d", &l, &r), qaq.insert(make_pair(l, r));
Work(qwq, res1), Work(qaq, res2);
for(int i = 0; i <= n; i++) Maxx = std::max(Maxx, res1[i] + res2[n - i]);
return !printf("%d\n", Maxx);
}

本文作者:TLE_Automation

本文链接:https://www.cnblogs.com/tttttttle/p/16373300.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   TLE_Automation  阅读(415)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起