当前位置: 首页 > news >正文

模拟【打牌游戏】

Problem - B - Codeforces

鲍勃喜欢在手机上玩一款有趣的塔防游戏。在游戏里,他需要出牌来击败对手!

有 n 张牌排成一个队列,称为牌组。在任意时刻,鲍勃只能打出牌组中前 k 个位置里的牌。每一轮,鲍勃会选择前 k 个位置中的一张牌,将其从牌组中移出并打出,然后把这张牌放回牌组末尾。换句话说,每一轮都会从队列的前 k 个元素中选一个,移到队列末尾,它后面的所有元素都向前移动一位。

其中有一张牌是胜利条件牌,鲍勃想尽可能多次打出它。但每张牌都有对应的消耗:第 i 张牌(初始在第 i 位)每次被打出时,会消耗鲍勃 ai​ 点能量。所有打出的牌的总消耗不能超过 m。胜利条件牌初始在队列的第 p 个位置

请你求出:在总消耗不超过 m 的前提下,胜利条件牌最多能被打出多少次。

输入

每个测试文件包含多组测试用例。第一行一个整数 t(1≤t≤5000),表示测试用例数量。

每组测试用例第一行包含四个整数 n,k,p,m:

  • n:牌的数量
  • k:每轮可选择的前 k 张牌
  • p:胜利条件牌的初始位置
  • m:总能量上限

第二行包含 n 个整数 a1​,a2​,…,an​(1≤ai​≤m),表示每张牌的消耗。

保证所有测试用例的 n 之和不超过 5000。

输出

对于每组测试用例,输出一行一个整数,表示胜利条件牌最多能被打出的次数。

输入样例

4 2 1 2 42 42 1 3 3 2 6 2 1 2 3 2 2 6 2 1 2 8 4 7 10 3 4 4 2 1 1 4 2

输出样例

0 6 2 1

样例说明

  1. 第一个测试用例:每轮只能打第一张牌,打出它就会耗尽所有能量。胜利牌是第二张,根本无法打出,答案为 0。

  2. 第二个测试用例:可以打任意一张牌。最优策略就是只打胜利牌,它消耗 1 点能量,总能量 6 点,最多打 6 次。

  3. 第三个测试用例:初始牌组为 [2,1, 2](胜利牌标红)。按如下方式出牌:

    • 打第一张 → 牌组变为 [1, 2, 2]
    • 再打第一张 → 牌组变为 [2, 2, 1]
    • 再打第一张 → 牌组变为 [2, 1, 2]
    • 打第二张(胜利牌)→ 牌组变为 [2, 2, 1]过程中胜利牌被打出 2 次,总消耗恰好 6。可以证明无法打出更多次。
  4. 第四个测试用例:最多只能打出胜利牌 1 次,通过一直打第 4 张牌即可实现。

1. 问题本质

我们需要最大化胜利牌的打出次数,且总能量消耗不超过m。核心原则是:打出胜利牌的附加成本越小,能打的次数越多

2. 关键观察

  • 要打出胜利牌,必须让它进入牌组前k位;
  • 每次打出任意牌后,该牌会移到队尾,因此打出胜利牌需要 “先处理挡路牌”;
  • 最优策略:处理挡路牌时,永远选消耗最小的牌,以此最小化附加成本,为胜利牌留出更多能量。

3. 解法拆分

我们将问题拆分为两步计算:

  1. 首次打出胜利牌的最小成本:让胜利牌第一次进入前k位所需的最小能量;
  2. 循环打出胜利牌的成本:首次打出后,每次循环打出胜利牌的固定最小成本;
  3. 总次数 = 首次次数 + 剩余能量 ÷ 循环成本。
#include <bits/stdc++.h> using namespace std; int a[5001]; int main() { int t; cin >> t; while (t--) { // 遍历每组测试用例 // 变量定义(核心变量) // n:牌总数 k:每轮可打前k张 p:胜利牌初始位置 m:总能量 // ans:首次打出胜利牌的最小总成本 df:胜利牌单次消耗 // s:循环打出一次胜利牌的总成本 o:胜利牌总打出次数 int n, k, p, m, ans=0, df, s=0, o=0; cin >> n >> k >> p >> m; // 第一阶段读取:分离胜利牌和其前方的挡路牌 // 读取前p张牌(包含胜利牌,胜利牌在a[p-1]位置) for(int i=0;i<p;i++){ cin>>a[i]; // 读取前p张牌 if(i==p-1) df = a[i]; // 单独保存胜利牌消耗(后续会被覆盖,需提前存) } // 关键:仅对胜利牌前方的p-1张牌排序(找最小消耗的挡路牌) // 胜利牌已用df保存,无需参与排序 sort(a, a + p - 1); // 计算首次打出胜利牌的最小成本 if(k >= p) { // 情况1:胜利牌初始就在前k位,无需打挡路牌,成本仅为胜利牌自身 ans = df; } else { // 情况2:胜利牌不在前k位,需打(p-k)张挡路牌才能让它进入前k位 // 选前p-1张中最小的(p-k)张,累加附加成本 for(int i=0; i < p - k; i++) { ans += a[i]; } // 首次总成本 = 挡路牌最小成本 + 胜利牌自身成本 ans += df; } // 判断首次是否能打出胜利牌 if(ans <= m) { o++; // 能打出则次数+1 } // 第二阶段读取:补充剩余牌,覆盖原胜利牌位置 // 从a[p-1]开始读取(覆盖原胜利牌位置),数组中只剩非胜利牌 for(int i=p-1; i < n-1; i++) { cin>>a[i]; } // 关键:对所有非胜利牌排序(找循环时最小消耗的附加牌) sort(a, a + n - 1); // 计算循环打出胜利牌的成本 int b = n - k; // 循环时,需打(n-k)张附加牌才能让胜利牌回到前k位 s = df; // 循环成本基础:胜利牌自身消耗 // 选所有非胜利牌中最小的b张,累加附加成本 for(int i=0; i < b; i++) { s += a[i]; } // 计算总次数:首次次数 + 剩余能量可支撑的循环次数 // 剩余能量 = 总能量 - 首次成本,除以循环成本得到循环次数 o += (m - ans) / s; // 输出每组测试用例的结果 cout << o << endl; } return 0; }

数组复用

  • 第一阶段:数组存 “胜利牌 + 前方挡路牌”,读取后立即用df保存胜利牌,避免后续覆盖丢失;
  • 第二阶段:从a[p-1]开始读取剩余牌,覆盖原胜利牌位置,让数组仅保留 “非胜利牌”,无需额外开数组。

局部排序

  • 第一次排序:仅排 “胜利牌前方的挡路牌”,精准匹配 “首次成本” 计算需求;
  • 第二次排序:仅排 “所有非胜利牌”,精准匹配 “循环成本” 计算需求;
  • 相比全局排序,减少无效计算,效率更高。

贪心策略

  • 首次成本:选最小的p-k张挡路牌,最小化首次附加成本;
  • 循环成本:选最小的n-k张附加牌,最小化每次循环的附加成本;
  • 最终通过 “最小成本” 最大化胜利牌打出次数。
http://www.jsqmd.com/news/491600/

相关文章:

  • 【2026年最新600套毕设项目分享】基于Java的宠物用品系统(14162)
  • 遍历 ES 节点校验分词:分布式集群分词一致性保障实践
  • 学习的规划
  • 损失厌恶:为什么失去100元的痛苦远超得到100元的快乐
  • 【多式联运】改进的ALNS算法冷藏品需求不确定下多式联运运输路线优化【含Matlab源码 15180期】
  • 口碑好的灌装及包装机企业
  • 每日一爽 3/16
  • 亲测鱼生酱油,这几款最专业
  • 龙虾技能系统大揭秘!如何安装和生产自己的skill
  • DHCP 技术课程课后总结
  • forum论坛搭建基于LNMP
  • 【数据结构与算法】5_python版 _队列
  • 国内主流的 龙虾 OpenClaw(AI 执行引擎/智能体)产品以及官网信息
  • 2026年便携式地下水位监测仪厂家排名与推荐 - WHSENSORS
  • openclaw-飞书正式版插件 部署攻略 windows
  • C# winform部署SAM2的onnx模型
  • 二十、Kubernetes基础-8-kubeadm-kubernetes-deployment-guide-04-networking
  • day01_基于Ollama+chatbox本地部署个模型玩玩
  • 应用层网络安全核心指南:从 HTTP 到 HTTPS 筑牢加密防护防线
  • 【征稿通知 | IEEE出版】第八届信息科学、电气与自动化工程国际学术会议(ISEAE 2026)
  • Doris的集群搭建(3FE+3BE)
  • 商业综合体消防改造防火卷帘门质量评测报告 - 优质品牌商家
  • L2-042 老板的作息表
  • VHD虚拟门禁:Windows新增设备配置指南
  • C语言100篇:从入门到天花板 第18篇 局部变量与全局变量:生命周期与访问规则
  • 【面试专栏|Java并发编程】为什么多线程读多写少场景,优先选CopyOnWriteArrayList?原理详解
  • 2026年足疗采耳加盟品牌专业选型指南:博足堂自主品牌加盟深度解析(足疗/采耳/按摩/修脚招商加盟) - 品牌推荐官
  • Django 学习 Part 3: 视图与模板系统
  • Web开发转Agent?3个顶尖大厂Offer经验分享,手把手教你学大模型开发!
  • 2026年浙江建筑资质延期/建筑资质咨询/建筑资质代办/建筑资质动态核查/建筑资质吸收合并/建筑资质转让/建筑资质升级服务商推荐:杭州瑞诚教育科技有限公司 - 2026年企业推荐榜