P7913 [CSP-S 2021] 廊桥分配
Solution
更新一下,之前写的太烂了。
首先我们能想到一个暴力算法,就是枚举分配到国内区和国外区的廊桥个数,然后用两个优先队列来模拟,复杂度
预计得分: 40
然后我们考虑,当一个区的廊桥数确定为 的时候,另一个廊桥数是 。
当一个区的廊桥数增加的时候,他能停靠的飞机只增不减。
如果我们给廊桥标上号,当增加廊桥数目之后,之前停靠在廊桥上的飞机不会停到新增加的廊桥上。
如果每一遍都模拟,复杂度过高,当一个区为 个廊桥时,我们可以利用有 个廊桥的结果算出 的结果。
表示在国内区前 个廊桥能停靠的飞机个数, 表示在国际区前 个廊桥能停靠的飞机个数。
我们可以通过前缀和来实现这个数组的求出,也就是求出每个廊桥可以停靠的飞机个数,我们可以维护两个优先队列,一个是空闲的廊桥,一个是要离开的飞机所停靠的廊桥。
这个过程的话,用什么数据结构维护一下就行了。
但是个人觉得 set 最简洁。
复杂度 , 预计得分
/* 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 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!