3.19 CW 模拟赛 T3. 软件工程

news/2025/3/20 10:19:52/文章来源:https://www.cnblogs.com/YzaCsp/p/18782499

前言

策略肯定是锅了, 基础上需要对策略进行一些修改
喵了个咪的最终还是要针对考试
谢特

某吴姓同学的策略是非常适合我的, 在它的基础上, 我们考虑进行一些本土化
首先花 \(20 \textrm{min}\) 思考每道题, 也就是每道题严格 \(5 \textrm{ min}\)

首先按照能拿到的 \(\rm{subtask}\) 数量排为新的 \(\textrm{T2, T3, T4}\)
然后还是像之前一样化固定时间去冲, 注意不贪跟策略

你发现因为 \(20 + 35 \times 4 = 160 = \textrm{2h 40min}\), 剩了约 \(\textrm{1h}\), 因此这样大概率不可能完成
因此考虑先把简单的 \(\rm{subtask}\) 拿了放弃一道最难的或者最不会的题, 剩下的拼分
反正差不多这样吧, 哎哎哎, 太难了

思路

男人, 什么罐头我说, 曼巴出去!

题意

给定若干线段
要求你把这些线段分成 kk 个集合, 每个集合的贡献是其中线段交的长度

求一种划分方式, 使得总贡献最大

去码头整点性质
凭感觉应该要先对线段排序之后做处理, 我们先按照左端点排一遍看有什么性质

考虑一种特殊情况, 即左右端点全部单增 \((\)我不会告诉你是因为我画草稿的时候忘了画包含情况不小心发现的\()\)
如下
pEwQaQK.png
这种情况下不难发现应该相邻分段, 考虑简单证明

证明

假设当前不是相邻分段的, 例如
pEwQ8o9.png

那么我们考虑将其调整为相邻的, 不难发现贡献显然更大

我知道你应该看不到图, 请自行脑补 但是这种情况有什么用呢, 题也没给这个特殊性质啊, 无语了

继续整点性质, 不然还是没法做题
自然地, 我们考虑如果有包含关系应该怎么办, 接着画图
pEwQJiR.png
看似这是一种情况, 但是显然
pEwQYJ1.png
这样更优

感觉也是有性质的, 只是说不太好找

pEwQ3dJ.png
看似这是一种情况, 但是显然
pEwQtRx.png
这样更优

所以初步猜测是要让上面几个单开, 下面的直接并到一起
这对吗?
应该很对啊

也就是把包含一条线段的分组, 然后这样子去做
那假如出现这种情况不就炸了吗
pEwQNz6.png

这是怎么分组的
发现按照被覆盖分组即可
也就是只保留第三跟第六根线段作为最终的结果

考虑具体怎么转移

\[f_{i, k} \gets \max\Big(f_{j, k - 1} + r_{j + 1} - l_i\Big) \]

这个真是太典了, 我们直接单调队列优化 + 滚动即可

实现

男人, 什么罐头我说, 曼巴出去!

代码
#include <algorithm>
#include <cstdio>
#include <vector>
#include <deque>const long long INF = 1e18;
const int MAXN = 5005;struct Segment { int l, r;bool operator<(const Segment& s) const {return l == s.l ? r > s.r : l < s.l;}
};int n, k;
Segment seg[MAXN];
long long global_res;// Case1: 存在空交集集合的情况
void handle_case1() {std::sort(seg + 1, seg + n + 1, [](auto& a, auto& b) {return a.r - a.l > b.r - b.l;});long long sum = 0;for (int i = 1; i < k; ++i)sum += seg[i].r - seg[i].l;int max_l = -1e9, min_r = 1e9;for (int i = k; i <= n; ++i) {max_l = std::max(max_l, seg[i].l);min_r = std::min(min_r, seg[i].r);}global_res = std::max(global_res, sum + std::max(0, min_r - max_l));
}// Case2: 所有集合交非空的情况
void handle_case2() {int m = 0;std::sort(seg + 1, seg + n + 1, [](const Segment& a, const Segment& b) {return a.l == b.l ? a.r > b.r : a.l < b.l;});std::vector<long long> le{0};for (int i = 1; i <= n; ) {while (m > 0 && seg[m].r >= seg[i].r) {le.push_back(seg[m].r - seg[m].l);m--;}m++;seg[m] = seg[i];i++;}std::sort(le.begin() + 1, le.end(), std::greater<long long>());while (le.size() <= k) le.push_back(0);for (size_t i = 1; i < le.size(); ++i)le[i] += le[i - 1];std::vector<long long> f(m + 1, -INF);f[0] = 0;for (int T = 1; T <= std::min(m, k); ++T) {std::vector<long long> g(m + 1, -INF);auto tmp = f;for (int i = 1; i <= m; ++i) {if (i - 1 >= 0 && i - 1 < tmp.size()) {tmp[i - 1] += seg[i].r;}}std::deque<int> q;for (int i = 1; i <= m; ++i) {while (!q.empty() && seg[q.front() + 1].r <= seg[i].l)q.pop_front();while (!q.empty() && tmp[q.back()] <= tmp[i - 1])q.pop_back();q.push_back(i - 1);g[i] = tmp[q.front()] - seg[i].l;}if (k - T >= 0 && k - T < le.size())global_res = std::max(global_res, g[m] + le[k - T]);f.swap(g);}
}int main() {scanf("%d%d", &n, &k);k = std::min(n, k);for (int i = 1; i <= n; ++i)scanf("%d%d", &seg[i].l, &seg[i].r);global_res = 0;handle_case1();handle_case2();printf("%lld\n", global_res);return 0;
}

总结

特有的最优解性质

比较 \(\rm{nb}\) 的观察到神秘贪心之后能够想到对其他情况做处理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/901907.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

生成AI的两大范式:扩散模型与Flow Matching的理论基础与技术比较

生成模型已成为人工智能领域的关键突破,赋予机器创建高度逼真的图像、音频和文本的能力。在众多生成技术中,扩散模型和Flow Matching尤为引人注目。这两种方法虽然都致力于在噪声与结构化数据之间建立转换,但其基础原理存在本质区别。本文将系统地比较这两种先进技术,深入探…

基于ACE_SOCK_Dgram的UDP同步通信

1、创建基于ACE_SOCK_DGRAM的UDP服务端1 void udp_server_base_on_synch()2 {3 // 1. 绑定服务端地址(端口 8080)4 ACE_INET_Addr server_addr(8080);5 ACE_SOCK_DGRAM sock;6 if (sock.open(server_addr) == -1) {7 std::cerr << "Serve…

第二十一章 项目管理科学基础(2025年详细解析版)

目录导学21.1 工程经济学资金的时间价值与等值计算定义常识现在值与将来值等值计算问题单利法与复利法 (利滚利)单利法复利法承兑汇票示例项目经济静态评价方法什么叫回收期?什么叫静态?静态投资回收期例题(必须掌握)投资收益率定义公式例题项目经济动态评价方法什么是动态…

windows输入法选用

前言 一直以来pc输入法都是用的搜狗,但是总想换一个用一用,每次都是尝试换讯飞,每次都用不下去。 不推荐 讯飞 bug极多。比如中文输入下,按shift,应该留下英文。当然一般情况下没问题,但是出现bug时,切换后再打字,会覆盖前面的字。 QQ 曾长期使用过,但是那时候用电脑用…

OpenTelemetry安装和使用

官网 https://opentelemetry.io/环境查看 系统环境# cat /etc/redhat-release Rocky Linux release 9.3 (Blue Onyx) # uname -a Linux Rocky9Opentelemetry003078 5.14.0-362.18.1.el9_3.0.1.x86_64 #1 SMP PREEMPT_DYNAMIC Sun Feb 11 13:49:23 UTC 2024 x86_64 x86_64 x86_…

大厂裁员不断,这个高薪岗位却找不到人?

《未来简史》写道:“未来属于那些能够快速适应变化、不断学习新技能的人。”大家好,我是陈哥。 当下,裁员潮席卷全球:微软裁撤万人级游戏部门,谷歌AI伦理团队被优化,亚马逊用机器人取代数万仓储岗位。然而,DevOps工程师的招聘却逆势而上。 据美国在线求职平台FlexJobs数…

跑酷P2 移动有害和切换关卡

跑酷游戏 第二集 本集中我们对上一集中的移动问题进行了优化,并且制作了关卡切换功能。 移动优化 上一集中,我们留下了一些移动方面的问题。首先是连跳问题,角色在空中可以不受限制的跳跃,我们需要解决一下。新建一个私有变量正在跳跃,用来存放角色跳跃的状态。在游戏开始…

跑酷P6 过关功能

跑酷游戏 第六集 本集我们实现了完成关卡的功能,并且修复了重新开始游戏后物资的bug。 角色绘制和显示逻辑 我们复制一下我们的物资角色,重命名为出口。然后绘制两个造型,一个是出口关闭的造型,一个是出口打开的造型。然后到我们的代码部分。我们的出口代码和物资角色的代码…

跑酷P6 关卡和金币系统

塔防游戏 第六集 本集主要实现了游戏的关卡处理和金币系统。 关卡处理 绘制一个开始按钮放置在画面左上方。我们希望在游戏开始时,或者一波关卡结束之后可以点击这个按钮,生成新一个关卡的敌人。我们新建一个全局变量关卡。游戏开始时关卡默认为0,每次开启一个新的关卡让这个…

跑酷P5 收集物资

跑酷游戏 第五集 本集我们实现了搜集物资的功能。 移动和复制 首先我们复制一遍场景角色,然后清空造型。复制的原因是我们移动和显示部分的代码逻辑,物资和场景是一样的。 然后我们来重新绘制造型。这里我们可以用自己喜欢的造型,金币,水果,宝石等都可以。这里我按视频的做…

读DAMA数据管理知识体系指南25数据集成活动

读DAMA数据管理知识体系指南25数据集成活动1. 规划和分析 1.1. 数据集成和互操作涉及在什么时间、什么地点、以什么方式能获得数据 1.2. 定义数据集成和生命周期需求1.2.1. 定义数据集成需求涉及理解组织的业务目标,以及为实现这些目标而需要的数据和建议的技术方案1.2.2. 数据…

塔防P9/P10 激光炮台和游戏结束判定

塔防游戏 第九/十集 这两集我们完成了一个新炮台——激光炮台,以及敌人碰到地图边缘扣除生命值导致游戏结束的功能。 绘制炮台 在炮台角色中绘制炮台的图片并复制到图标一份,绘制炮台不可选中的图标和炮台的开火动画。我们设计激光炮台的开火前有短时间的蓄力过程,我们需要两…