好题记录 [集训队互测 2023] 优惠购物 题解

首先发现这个过程的限制比较多,那么考虑重新描述这个过程。

xi 表示在第 i 个物品上使用了 xi 张券,那么一组 x1n 就描述了一个方案。

方便起见,令 si 为前 i 个物品买完后剩了几张券,那么有:

  • s0=m
  • si=si1+aixic

考虑合法的 x1n 要满足的条件和最后的答案。

要满足的条件:

  1. xibi
  2. xisi1

最后的答案为 (aixi),即要求最大化 xi

先考虑所有 xi=0 的情况,然后考虑变化,设 dsi 为第 i 个物品贡献的优惠券。

基于 dsi 的变化,可以把一个物品的 xi 的变化拆成基于 3 种操作的变化。

  1. aimodc 张,此时使用优惠券不影响 dsi
  2. 每次操作使 dsi 减 1 并使 xic
  3. 使 dsi 减 1 并使 xi[0,c1]

为了方便考虑,设 si=si1xi,那么条件 2 就是 si0

接下来再次考虑每种操作造成的影响。

i 进行操作 1/2/3 的影响分别为:

  1. 使 sin 全部减 1xi1
  2. 使 sic,使 sj>ic+1,使 xic
  3. 假设使 xiz,那么会使 siz,使 sj>iz+1

发现:

  1. 显然操作 2 优于操作 3,且操作 1 优于其余两个(因为相同情况下影响一定完全小于其余操作)。
  2. 为了进行最多次的操作 1 可以从右往左扫一遍。
  3. 为了进行最多次的操作 2 也可以从右往左扫一遍。

那么我们考虑动态维护 si 的值。令 t 为能使用的券的个数。

对于操作 1,t=min(bi,aimodc,minjisj)

对于操作 2,t=min(bixic,si1c,minjisjc+1)×c

(我的正解的操作 3 部分的代码写得很丑陋,大概看一下就行。)

对于操作 3,考虑最优策略按能使用的券的张数从大到小,那么我们可以直接暴力模拟,t=min(bixi,min(si1,di=minjisj1))

发现 dii 增大而增大。那么考虑枚举前面的限制(bixi),把 w 的加入,然后看一下最大的 idi,比较一下大小即可,可以用区间加,查询区间 min 线段树维护。

可以看一下暴力模拟的代码,正解用某些方式优化了其中的过程。

暴力模拟代码1
暴力模拟代码2

正解代码

posted @   SkyMaths  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
历史上的今天:
2023-11-12 Tenzing and Random Operations CF1842G 题解
点击右上角即可分享
微信分享提示