Loading

[每日 C] Cards Partition

前言

以一道绿结束今天的每日 \(\rm{C}\) 比较合理

思路

你发现假设分成大小为 \(s\) 的副牌, 只要满足

\[s \mid \sum_{i = 1}^{n} a_i \textrm{ and } \forall i \in [1, n], a_i \leq \frac{\sum_{i = 1}^{n} a_i}{s} \]

即可

考虑贪心的买新牌, 每次只需要把小的补上去即可
也就是说, 在最初补满 \(a_i\) 之后, 以后每新买 \(n\) 张牌就会使得 \(\max a_i\) 加一

那么怎么实现

首先你计算出把 \(a_i\) 补满的花费 \(C\) , 简单分类讨论

\(k \leq C\)

这种情况下, 不管怎么填, \(\max a_i\) 固定
可以计算出 \(\sum a_i\) 的取值区间, 然后 \(\mathcal{O} (n)\) 判断最大的 \(k\) 使其符合要求

\(k > C\)

这种情况下稍微要复杂一点
首先同上计算, 然后令 \(k \gets k - C\)
你发现对于现在的 \(k\) , 每放 \(n\) 个就会使得 \(\max a_i\) 加一, 考虑 \(k\) 可以产生 \(\max a_i\) 的区间, 对于整段直接判断, 对于前后的小段你 \(\mathcal{O} (n)\) 检查即可


看完题解觉得自己是弱智

你考虑对于每一个 \(s\) 怎么判定

\(\sum_{i = 1}^{n} a_i < s \times \max a_i\)

显然的, 只要 \(\sum_{i = 1}^{n} a_i + k \geq s \times \max a_i\) 即可, 原因是当 \(\sum_{i = 1}^{n} a_i = s \times \max a_i\) 时, 一定是最优秀的补数同时满足以上两种条件

\(\sum_{i = 1}^{n} a_i \geq s \times \max a_i\)

只要 \([s - (\sum_{i = 1}^{n} a_i \textrm{ mod } s)] \textrm{ mod } s \leq k\) 即可

具体的, 你画画图可以发现, 去补的时候会在上面均匀的加几层, 虽然 \(\max a_i\) 发生了变化, 但是仍然满足条件


思维绿那不复习一下?

题意

nn 类物品, 第 ii 种有 aia_i
你可以任意购买小于等于 kk 个这 nn 类物品形成新的 ai{a^{\prime}}_i

剩下的问题构成了一个经典贪心

经典贪心策略

给定 nn 类物品, 第 ii 种有 aia_i
求一个把所有物品归组的方法, 使得每组中不存在同类物品, 并使得组的大小最大

不难发现
假设组的大小为 KK , 有 ansans 组, 那么可以这样构造
构造方案

首先本题中不允许有余下的物品
因此有, i=1naiK×maxai,Ki=1nai\sum_{i = 1}^{n} {a'}_i \geq K \times \max {a'}_i, K | \sum_{i = 1}^{n} {a'}_i
问题转化成这样

对于一组合法的 ai{a'}_i , 其收益为最大的 KK 使得 i=1naiK×maxai,Ki=1nai\sum_{i = 1}^{n} {a'}_i \geq K \times \max {a'}_i, K | \sum_{i = 1}^{n} {a'}_i , 求收益最大的 ai{a'}_i

怎么处理?
公式化做题

  • 定义操作 (约束) 和开销 / 收益, 要求最值化开销 / 收益
    • 将约束条件数学化
    • 模拟操作情况, 贪心处理最好开销 (将简单情况先处理, 然后在基础上处理最值 / 简化操作)
    • 考虑操作对答案的影响 (推式子) , 据此对操作进行处理
      • 推导每个元素对答案的贡献 \((\)拆贡献\()\)
      • 推导动态规划
    • 枚举开销所需要的一个值\((\)超过 \(x\) / 不大于 \(x\) / 和小于 \(x\) 中的 \(x\)\()\) , 然后考虑对于这个值进行
      • 贪心
      • 判断

考虑枚举 \(K\) 进行判断
不妨记 \(\sum a_i = S, \max a_i = v\) , \(\sum {a'}_i = S', \max {a'}_i = v'\)

  • \(k \leq v \times n - S\)
    不难发现 \(v' = v\)
    问题简化为判断是否存在 \(S' \in [S, S + k]\) , 使得 \(K | S', Kv \leq S'\)
    也就是判断 \([Kv, S + k]\) 中是否有 \(K | S'\)
    也就是判断 \(Kv \leq S + k\)
  • 否则
    首先同理处理 \(k' \leq v \times n - S\) 的部分
    那么现在只需要判断 \(v \times n - S \leq k' \leq k\) 的部分中是否存在答案
    也就是说, 是否存在 \(S' \in [nv, S + k]\) , 使得 \(K | S', K\Big(v + (S' - {nv} \textrm{ mod } n)\Big) \leq S'\)
    把条件甩出来

    \[K | S', K\Big(v + (S' - nv \textrm{ mod } n)\Big) \leq S' \\ \Downarrow \\ K | S', K\Big(v + (S' \textrm{ mod } n)\Big) \leq S' \\ \Downarrow \\ K | S', K(S' \textrm{ mod } n) \leq S' - Kv \\ \]

    好吧不行, 换思路
    首先不难判断是否存在 \(S' \in [nv, S + k]\) , 使得 \(K | S'\) , 可以用 \(\left\lfloor \frac{S + k}{K} \right\rfloor \times K \geq nv\)
    现在问题简化为 判断 \(Kv' \leq S'\) , 发现 \(v'\) 增长速度远远小于 \(S'\) 增长速度, 所以我们找到最大的满足 \(K | S'\)\(S'\) , 然后判断 \(Kv' \leq S'\) 一定最优

总结

一类贪心

注意一定要把思路弄得明白再去打代码, 然后也就是不要慌, 代码错了检查思路
注意根据问题复杂度简化思路, 不去考虑不影响答案的情况

不过这个题, 知道这类贪心的做法之后就简单了, 否则并不好想
这个贪心的思路其实就是构造方法的差别
具体一点就是能不能想到 这种方法 去构造

解不等式的策略

  • 直接硬转, 判断存在性
  • 贪心的令不等式的条件最容易成立, 只要有一个成立即可
    • \(\textrm{exp.}\) 增长速度左边慢于右边, 要求左边小于右边, 直接把时间拉到最大
posted @ 2025-01-14 15:06  Yorg  阅读(18)  评论(0)    收藏  举报