D. Serval and Kaitenzushi Buffet

news/2025/3/26 14:12:52/文章来源:https://www.cnblogs.com/archer233/p/18789912

Serval and Kaitenzushi Buffet 题解:优先队列 + 数学推导

题目链接

题目分析

Serval 在一家回转寿司餐厅用餐,他需要在 $ n $ 分钟内最大化所吃寿司的美味值总和。每盘寿司有 $ k $ 块,第 $ i $ 盘寿司的美味值为 $ a_i $。在每一分钟,Serval 可以选择以下操作之一:

  1. 取走当前盘子,增加未吃完的寿司块数 $ r $(即 $ r += k $)。
  2. 吃掉一块寿司,减少未吃完的寿司块数 $ r $(即 $ r -= 1 $)。
  3. 什么都不做,保持 $ r $ 不变。

最终,$ r $ 必须为 0(即所有寿司都必须吃完)。我们需要帮助 Serval 最大化他取走的所有盘子的美味值总和。

听起来有点复杂?别急,我们慢慢来~


思路大意

这道题的核心目标是找到一种策略,使得 Serval 能够在 $ n $ 分钟内尽可能多地取走高美味值的盘子,并保证所有寿司都能被吃完。

核心观察

为了最大化美味值总和,我们需要尽可能多地取走高美味值的盘子,并保证在 $ n $ 分钟内可以吃完所有寿司。

数学推导

假设我们选择了 $ m $ 盘寿司,则总共需要吃 $ m \times k $ 块寿司。由于每分钟最多只能吃 1 块寿司,因此完成这些寿司需要至少 $ m \times k $ 分钟。同时,我们还有 $ n - m $ 分钟用于取盘子或什么都不做。

因此,满足条件的 $ m $ 必须满足以下不等式:

\[m \times (k+1) \leq n \]

即:

\[m \leq \left\lfloor \frac{n}{k+1} \right\rfloor \]

这意味着我们可以最多取走 $ \left\lfloor \frac{n}{k+1} \right\rfloor $ 盘寿司。

接下来的问题是如何选择这 $ m $ 盘寿司以使美味值最大。显然,我们应该优先选择美味值最高的盘子。


算法设计

基于上述分析,我们可以设计如下算法:

  1. 使用一个优先队列priority_queue<int>)来维护当前遇到的盘子的美味值。
  2. 遍历所有盘子,将每个盘子的美味值加入优先队列。
  3. 当遍历到某个时刻时,判断是否应该从优先队列中取出一个盘子计入答案。具体地,当剩余时间不足以处理更多的盘子时,我们就应该从优先队列中取出一个盘子。

代码详解

以下是完整的代码实现及其详细解释:

#include <bits/stdc++.h>
#define int long long
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define pb push_back
#define pii pair<int,int>
using namespace std;
const int mod = 998244353;void solve() {int n, k; cin >> n >> k; // 输入 n 和 kvector<int> a(n + 1); // 存储每盘寿司的美味值for (int i = 1; i <= n; i++) cin >> a[i]; // 输入美味值priority_queue<int> pq; // 优先队列,存储当前遇到的盘子的美味值int ans = 0; // 答案初始化为 0for (int i = 1; i <= n; i++) {pq.push(a[i]); // 将当前盘子的美味值加入优先队列// 判断是否需要从优先队列中取出一个盘子if ((n - i) % (k + 1) == k) {ans += pq.top(); // 取出当前美味值最大的盘子pq.pop(); // 从优先队列中移除该盘子}}cout << ans << endl; // 输出答案
}signed main() {ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); // 加速输入输出int _ = 1; cin >> _; // 测试用例数量while (_--) solve(); // 处理每个测试用例
}

代码关键部分解析

priority_queue<int> pq;

  • 作用:优先队列是一种数据结构,能够高效地维护一组元素,并支持快速插入和删除最大值的操作。
  • 特性:在本题中,我们使用优先队列来存储当前遇到的所有盘子的美味值,并始终保持美味值最大的盘子在队列顶部。
  • 时间复杂度:插入和删除操作的时间复杂度均为 $ O(\log m) $,其中 $ m $ 是队列中的元素数量。

关键逻辑

for (int i = 1; i <= n; i++) {pq.push(a[i]);if ((n - i) % (k + 1) == k) {ans += pq.top();pq.pop();}
}

逐行解释

  1. pq.push(a[i]);

    • 将当前盘子的美味值 $ a[i] $ 加入优先队列。
    • 此时,优先队列会自动调整内部结构,确保队列顶部始终是当前美味值最大的盘子。
  2. if ((n - i) % (k + 1) == k)

    • 这是判断是否应该从优先队列中取出一个盘子的关键条件。
    • 条件的核心思想是:在某些特定时刻,剩余时间不足以处理更多的盘子,因此我们需要从优先队列中取出一个盘子计入答案。
    • 具体地,当剩余时间 $ (n - i) $ 满足 $ (n - i) \mod (k + 1) == k $ 时,表示我们已经无法再取新的盘子,而应该开始选择之前取过的盘子。
  3. ans += pq.top();pq.pop();

    • 当满足条件时,从优先队列中取出当前美味值最大的盘子,并将其加入答案。
    • 同时,将该盘子从优先队列中移除。

数学公式的进一步解释

条件 \((n - i) \% (k + 1) == k\)

这个条件的含义可以通过以下推导理解:

  • 设当前时间为 $ i $,则剩余时间为 $ n - i $。
  • 如果我们要在剩余时间内处理完所有已取的盘子,则需要满足:

    \[\text{已取盘子数} \times k \leq \text{剩余时间} \]

  • 换句话说,如果我们已经取了 $ m $ 盘寿司,则需要满足:

    \[m \times k \leq (n - i) \]

  • 当 $ (n - i) % (k + 1) == k $ 时,表示剩余时间刚好足够处理一个新的盘子,因此我们需要从优先队列中取出一个盘子。

示例分析

输入

5
5 2
3 6 4 1 2
7 1
3 1 4 1 5 9 2
4 3
4 3 2 1
6 2
1 3 5 2 4 6
6 1
1000000000 1 1000000000 1 1000000000 1

输出

6
16
4
6
3000000000

解释

  1. 第一个测试用例

    • $ n = 5, k = 2 $
    • 盘子美味值为 $ [3, 6, 4, 1, 2] $
    • 最多可以取 $ \left\lfloor \frac{5}{2} \right\rfloor = 2 $ 盘寿司。
    • 选择美味值为 $ 6 $ 的盘子,最终答案为 $ 6 $。
  2. 第二个测试用例

    • $ n = 7, k = 1 $
    • 盘子美味值为 $ [3, 1, 4, 1, 5, 9, 2] $
    • 最多可以取 $ \left\lfloor \frac{7}{1} \right\rfloor = 7 $ 盘寿司。
    • 选择美味值为 $ 3, 4, 9 $ 的盘子,最终答案为 $ 16 $。

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

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

相关文章

Gitee DevOps 实践指南:本土团队效率提升的新范式

在数字化转型的浪潮中,Gitee DevOps 作为国内领先的一体化研发效能平台,通过深度融合代码托管、CI/CD、项目管理等核心功能,为企业提供了本土化的 DevOps 解决方案。一、Gitee DevOps 的核心价值定位 在数字化转型的浪潮中,Gitee DevOps 作为国内领先的一体化研发效能平台,…

那些正常的动态规划

目录前言动态规划到底是啥?线性dp最长上升子序列子集和子序列和子串的区别内容分析最大上升子序列例题1——[NOIP2004 提高组] 合唱队形分析最长公共子序列最长公共子串平面dp例题2——[NOIP2000 提高组] 方格取数分析例题3——[NOIP2008 提高组] 传纸条分析例题4——最大加权…

3月24日刷题笔记-第六章 流量特征分析-常见攻击事件 tomcat

1、在web服务器上发现的可疑活动,流量分析会显示很多请求,这表明存在恶意的扫描行为,通过分析扫描的行为后提交攻击者IP flag格式:flag{ip},如:flag 我们查看流量包,可以发现有一个外部IP在对常见端口进行SYN扫描,判断出为恶意IPflag{14.0.0.120} 2、找到攻击者IP后请通过…

如何在云效中使用 DeepSeek 等大模型实现 AI 智能评审

除了代码智能补全外,AI 代码智能评审是 DevOps 领域受开发者广泛关注的另一场景了。本文,我们将结合云效代码管理 Codeup、流水线 Flow 和 DeepSeek,分享一种企业可快速自主接入,即可实现的 AI 智能评审解决方案,希望给大家一些启发。作者:崔力强、黄博文 除了代码智能补…

T+0量化:JAVA接入Level2高频行情(附Python代码)

去年在知乎分享过一个网格策略,评论区全是"代码能跑通但实盘不敢用"的留言。当时我也一样——用第三方平台回测美滋滋,一到实盘就怂:行情延迟3秒、API调用次数受限、策略逻辑被平台规则卡脖子…直到把整套系统搬回本地,才发现自建交易系统的快感就像从合租屋搬进…

制作一个简单的带有3D打印部件的四足蜘蛛机器人

在这个项目中,我将向您展示如何使用3D打印部件制作一个简单的4腿行走蜘蛛机器人。该设计主要由上下板、臂接插件、腿和伺服支架五个部分组成。机器人的4条腿由4个手臂部分和4个腿部分组成。机器人的运动总共使用了8个业余伺服电机,4个在手臂上,4个在腿上。在电路方面,首选E…

统计学习之数据挖掘(结构数据)

统计学习之数据挖掘(结构数据):降维聚类关联度分析分类神经网络

2024 腾讯游戏安全大赛 mobile 初赛 wp

找关键结构体 https://www.cnblogs.com/revercc/p/17641855.html 找GWORLD https://bbs.kanxue.com/thread-280042.htm可以发现是 TEXT包裹的,utf-16编码,ida alt + b搜索 53 00 65 00 61 00 6D 00 6C 00 65 00 73 00 73 00 54 00 72 00即可网上翻即可找到 GWorld对应地址: 0…

制造业订单处理烦恼多,日事清 OTD 管理为您排忧解难

你是不是经常因为接单和交货时间差太大而焦头烂额?今天我们就结合制造业OTD管理,带您了解如何应用日事清进行订单交付全周期管理。日事清可以帮你设定精细的流程,从接单到发货,清晰可控地帮你解决以上烦心事。在制造业里打拼,每天都得面对各种烦心事,比如订单处理慢、生产…

如何在SSD1306上显示动态表情符号位图

解锁您的SSD1306上充满活力的视觉效果!学习毫不费力地显示动态表情符号位图,并以风格增强您的项目。 在本教程中,我们将通过使用PCBX在线模拟环境在SSD1306 OLED显示器上显示位图图像的过程。本教程将介绍设置PCBX模拟,格式化位图数据,配置显示大小和管理图像延迟。步骤1:…

redis基础数据结构——ZipList

ZipList 基于特殊写法实现的双端链表,由一系列特殊编码的连续内存块组成,可以像deque一样在双端压入/弹出,并且时间复杂度在O(1) 整体ZL结构如下zlbytes(uint32):当前zl总的byte数。 zltail(uint32):尾结点的offset,指向的是最后一个entry的起始地址。 zllen(uint16):记…