做题笔记

abc375_d 字符串前缀和


字符串前缀和


括号DP


P6155修改 贪心

  注意到性质:修改的个数越少越好。当我们需要使 \(a_i\) 与序列中其他数不同时,即使选择“修改 多个非 \(a_i\) 的数 ”与“ 修改 \(a_i\) ”所需要的修改次数相等,但是由于我们可以把最小的 \(b_i\) 分配给 \(a_i\),而修改不同的数需要用到不同的 \(b_i\),且这些 \(b_i\) 不会小于最小的 \(b_i\),我们可以判断:只修改一个数的代价最优

  思路:找到每个 \(a_i\) 修改后的值,计算所需的修改次数。我们需要让修改的数的个数最少,并将修改次数最多的数分配最小的 \(b_i\)

  在实现中,我们需要让 \(a_i\) 从大到小 排序。这样可以让修改的数的个数更少,正确性显然。

Record.


P4447分组 贪心

  要求最小值最大,考虑二分答案。

  数组 \(q_i\) 的意义是在第 \(i\) 组中如果想要再放一个数,这个数应该是多少。数组 \(siz_i\) 的意义是第 \(i\) 组有多少个人。

  我们在 \(q\) 中寻找可以放下 \(a_i\)\(q_{pos}\), 当找到第一个满足要求的 \(q_{pos}\) 之后,接着尝试往后找满足要求的 \(q_{pos + 1}\)。因为越靠后的 \(q\) 越晚被建立,故其存储的答案会更小。我们将当前 \(a_i\) 累加到尽量小的 \(q\),可以尽量满足最小值最大的题意。

  接下来,如果可以在当前的 \(q_{pos}\) 中放下 \(a_i\) 那么就放。并且把 \(q_{pos}\)\(siz_{pos}\) 分别加1;如果不行,那么需要新建一个 \(q_{cnt + 1}\) 来存放这个人。 \(q_{cnt + 1} = a_i + 1\)\(siz_{cnt}\) 设为1。

  最后答案为 \(\min_{1 \le i \le cnt}\{siz_i\}\)

Record.


P11268买东西题 反悔贪心

  反悔贪心。

  将优惠券按照 \(w_i\) 升序排序,将物品按照 \(a_i\) 升序排序。

  令 \(j < i\),且 \(j\) 使用优惠券 \(v_j\)

  • 对于 \(j\)

    • 使用优惠券。花费 \(a_j\) - \(v_j\)
  • 对于 \(i\)

    • 使用折扣价。花费 \(b_i\)
    • 使用不同于 \(v_j\) 的优惠券。花费 \(a_i - v_i\)
    • 抢走 \(j\) 的优惠券:
      • \(i\) 的花费为 \(a_i - v_j\),而 \(j\) 的花费变成 \(b_j\)
      • 此时 \(i\)\(j\) 的总花费变化为:\((a_i - v_j) - (a_j - v_j) + (b_j) = a_i - (a_j - b_j)\)。我们发现这个操作事实上等价于对 \(i\) 使用了一张 \(a_j - b_j\) 的优惠券。

  我们使用 priority_queue 来维护。

  • 对于每个物品 \(i\),我们将它能使用的优惠券压入优先队列中,并对 \(i\) 进行决策:
    • 如果使用折扣价更加优惠,直接使用折扣价;
    • 如果使用优惠券更加优惠,使用优惠券。弹出使用过的优惠券并压入一个新的价值为 \(a_i - b_i\) 的优惠券,以便后续的物品需要抢夺 \(i\) 的优惠券(如果需要)。

  每个元素仅被压入和弹出一次,时间复杂度为 \(O(n\log n)\)

Record.


P2882 [USACO07MAR] Face The Right Way G

区间翻转(异或)的 \(O(1)\) 差分实现。

posted @ 2024-10-29 22:23  QianXiquq  阅读(23)  评论(0)    收藏  举报